The answer below is wrong, but I'll keep it for others to learn from it (see below)
In ExampleA, you can use the same Config instance across multiple classes. However, if there should be only one Config instance within the entire application, consider applying the Singleton pattern on Config to avoid having multiple instances of Config. And if Config is a Singleton, you could do the following instead:
class ExampleA
{
private $config;
public function __construct()
{
$this->config = Config->getInstance();
}
}
$exampleA = new ExampleA();
In ExampleB, on the other hand, you'll always get a separate instance of Config for each instance of ExampleB.
Which version you should apply really depends on how the application will handle instances of Config:
- if each instance of
ExampleX should have a separate instance of Config, go with ExampleB;
- if each instance of
ExampleX will share one (and only one) instance of Config, use ExampleA with Config Singleton;
- if instances of
ExampleX may use different instances of Config, stick with ExampleA.
Why converting Config into a Singleton is wrong:
I must admit that I only learned about the Singleton pattern yesterday (reading the Head First book of design patterns). Naively I went about and applied it for this example, but as many has pointed out, one way are another (some have been more cryptic and only said "You're doing it wrong!"), this is not a good idea. So, to prevent others from making the same mistake that I just did, here follows a summary of why the Singleton pattern can be harmful (based on the comments and what I found out googling it):
If ExampleA retrieves its own reference to the Config instance, the classes will be tightly coupled. There will be no way of having an instance of ExampleA to use a different version of Config (say some subclass). This is horrible if you want to test ExampleA using a mock-up instance of Config as there is no way to provide it to ExampleA.
The premise of there will be one, and only one, instance of Config maybe holds now, but you cannot always be sure that the same will hold in the future. If at some later point it turns out that multiple instances of Config will be desirable, there is no way of achieving this without rewriting the code.
Even though the one-and-only-one instance of Config is maybe true for all eternity, it could happen that you want to be able to use some subclass of Config (while still having only one instance). But, since the code directly gets the instance via getInstance() of Config, which is a static method, there is no way to get the subclass. Again, code must be rewritten.
The fact that ExampleA uses Config will be hidden, at least when just viewing the API of ExampleA. This may or may not be a bad thing, but personally I feel that this feels like a disadvantage; for instance, when maintaining, there is no simple way of finding out which classes will be affected by changes to Config without looking into the implementation of every other class.
Even if the fact that ExampleA uses a Singleton Config is not a problem in itself, it may still become a problem from a testing point of view. Singleton objects will carry state which will persist until the termination of the application. This can be a problem when running unit tests as you want one test to be isolated from another (i.e. that having executed one test should not affect the outcome of another). To fix this, the Singleton object must be destroyed between each test run (potentially having to restart the whole application), which may be time-consuming (not to mention tedious and annoying).
Having said this, I'm glad that I made this mistake here and not in the implementation of a real application. In fact, I was actually considering rewriting my latest code to use the Singleton pattern for some of the classes. Although I could easily revert the changes (everything is stored in an SVN, of course), I would still have wasted time doing it.