Been getting more and more in applying proper methodologies to code in a testable manner and the past 2 weeks have drastically changed my approach when starting a small app from scratch.
Since I very often have to write small php console applications, my current target is to have a minimal application methodology that initialises a small application in a testable manner. Just want the usual classes for config, DB connection with a properly used singleton , error_handling configuration and logging.
I have approached this in quite a few different ways, but as of right now I have no clue if I am at all in the proper direction. Reading up on posts about dependency injection, I have come to try creating objects that have objects as parameters all the while respecting the law of Demeter for easy mocking. I have eliminated global constants that were not truly constants. I have just eliminated most static calls, and for the needed singletons such as app-wide DB connection, trying to apply Mr Hevery's suggestions and contain/wrap it in an object that will be passed along with other needed objects in the collaborating classes.
This is a very simplistic example straight from the top of my head from what I have pieced together so far. The approach I am looking into is to use a class AppFactoryHelper that acts as a very simple factory and creates the objects noted above.
I create a config object that is just a regular array with getters and setters, a DB singleton connexion, a logger object, and the error_handling class all through this factory, ie:
// very sketchy outline of programm flow for initialisation, stripped of error handling
require_once 'includes/settings.php';
require_once 'AppHelperFactory.php';
require_once 'container.php';
// object to load in container
$appObjects = array = ('log', 'db', 'error_handling');
$appHelperFactory = new AppHelperFactory;
//config object will be needed helper objects
$config = $appHelperFactory->createConfig($settings.php); //
// create dependency container, sets config object as private property inside,
// container holds only getters for $config.
$container = $appHelperFactory->createContainer($config);
try{
foreach($appObject as $className){
$methodName = 'create' . $className;
$container->{$value} = $appHelperFactory->{$methodName}($config);
}
$app = new ObjectThatWillFinallyGetSomethingDone($container);
$app->doStuff();
This approach has raised questions though. Am I using dependency injection even close to the proper way I should? is the DB singleton better off in a container that way? And the thing that bugs me all the time in testing, how would I test my "main" file?