views:

47

answers:

1

I have a few classes, such as those that outline database table structure or those that outline the application's configuration, which do not change state at all throughout the program's execution. I currently have these classes as singletons and the classes that wish to retrieve information request the class instances (eg. from the common getInstance() method) and then proceed to retrieve the information they desire. While this works, I was hoping to allow more modularity when it comes to configurations and this is where I am stuck.

My main goal is to allow easier debugging with modular configuration while still preserving code readability. I'm not sure how I will allow the ability to swap configurations for debugging sake without including Yet Another Singleton(tm) from which the classes who use the configuration settings can retrieve the proper configuration instances.

This is for a PHP web application, but isn't tagged as such because I'm guessing the solution will most likely be language independent.

Edit: To clarify my question, even though dependency injection is tickling my fancy as far as answers to my question go, let me provide a (perhaps oversimplified) example.

Let's say I have a wrapper for PHP's Mysqli class which will simply use whatever connection information is identified in the Config singleton...

class Mysql {
    // ...
    private $mysqli;

    public function __construct() {
     $conf = Config::getInstance(); // Get the configuration
     $this->mysqli = new Mysqli(
      $conf->getHost(),
      $conf->getUsername(),
      $conf->getPassword()
     );
     // ...
    }
    // ...
}

In this example, the Mysql class will accept only what settings are contained in Config, and it isn't possible to use any configuration except that contained in Config. In this example it might make more sense to simply past the host/username/password/whatever else to the constructor, but then it falls on client using the Mysql class to retrieve it from the Config singleton, and the problem manifests itself again in many more classes. Because it ultimately always retrieves dependencies from Config, it's not possible to easily try different settings with this set up.

From what I have been reading in a few places including the wonderful comments here, it seems like dependency injection is my best bet. For prospective readers in the future, one nice article on dependency injection with regard to PHP I found here, along with a simplified introduction to the concept (in Java) here.

+1  A: 

This is a major precept to dependency injection. The idea is to inject one instance of a class during runtime. During testing, you inject something else that has the same interface. It could be a dummy class, a mock object, or a regular instance created by the test with the expected state.

sblundy