I would avoid the Singleton approach suggested by Flavius. There are numerous reasons to avoid this approach. It violates good OOP principles.
The google testing blog has some good articles on the Singleton and how to avoid it: googletesting.blogspot.com/2008/08/by-mi... googletesting.blogspot.com/2008/05/tott-... googletesting.blogspot.com/2008/08/where... Alternatives a service provider java.sun.com/blueprints/corej2eepatterns... dependency injection en.wikipedia.org/wiki/Dependency_injection and a php explanation: http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection This is a good article about these alternatives: http://martinfowler.com/articles/injection.html Implementing dependency injection (DI): I believe you should ask what is needed in the constructor for the object to function: new YourObject($dependencyA, $dependencyB); You can provide the needed objects (dependencies) manually ($application = new Application(new MessageHandler()). But you can also use a DI framework (the wikipedia page provides links to PHP DI frameworks). Important is that you only pass in what you actually use (call an action on), NOT what you simply pass to other objects because they need it.
Here's a recent post from 'uncle Bob' (Robert Martin) discussing manual DI vs using framework. Some more thoughts on Flavius's solution. I don't want this post to be an anti-post but I think it's important to see why dependency injection is, at least for me, better than globals.
Even though it is not a 'true' Singleton implementation, I still think Flavius got it wrong. Global state is bad. Note that such solutions also use difficult to test static methods.
I know a lot of people do it, approve it and use it. But reading Misko Heverys blog articles (a google testability expert), rereading it and slowly digesting what he says did alter the way I see design a lot. If you want to be able to test you application, you'll need to adopt a different approach to designing your application.
When you do test-first programming, you'll have difficulty with things like this: 'next I want to implement logging in this piece of code; let's write a test first that logs a basic message' and then come up with a test that forces you to write and use a global logger that can't be replaced. I am still struggling with all the information I got from that blog, and it's not always easy to implement, and I have many questions. But there's no way I can go back to what I did before (yes, global state and Singletons (big S)) after I grasped what Misko Hevery was saying :-).
Thanks for the links. Will give them a read soon. – Pekka Nov 28 '09 at 18:17 +1 for DI.
Although I don't use it as much as I'd like to, it's been very helpful in whatever small quantities I did use it on. – Anurag Jan 23 '10 at 1:39 1 @koen: Care to give a PHP example of a DI / SP implementation in PHP? Maybe @Flavius code implemented using the alternative patterns you suggested?
– Alix Axel Jan 23 '10 at 2:49 Added a link to DI implementation and container in my answer. – Thomas Jan 23 '10 at 11:23 3 +1 Awesome links to Misko Heverys posts - it's making me thing twice... – Xeoncross Jan 23 '10 at 4:51.
I like the concept of Dependency Injection: "Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. (From Pico Container Website)" Fabien Potencier wrote a really nice series of articles about Dependency Injection and the need to use them. He also offers a nice and small Dependency Injection Container named Pimple which I really much like to use (more info on github).
As stated above, I don't like the use of Singletons. A good summary on why Singletons aren't good design can be found here in Steve Yegge's blog.
I like the implementation through Closures in PHP, very interesting reading – Juraj Blahunka Jan 23 '10 at 13:48 Me too an he has some other need stuff regarding closures on his site: fabien.potencier. Org/article/17/… – Thomas Jan 23 '10 at 15:22 2 let's hope, that mainstream webhouses will migrate to PHP 5.3 soon, as it is still not common to see a full featured php 5.3 server – Juraj Blahunka Jan 23 '10 at 15:28 They will have to, when more and more projects require PHP 5.3 like Zend Framework 2.0 will framework.zend. Com/wiki/display/ZFDEV2/… – Thomas Jan 23 '10 at 17:21 1 Dependency injection was also accepted answer on question about decupling from GOD object: stackoverflow.Com/questions/1580210/… with a very nice example – Juraj Blahunka Jan 23 '107 at 22:26.
Class Application { protected static $_singletonFoo=NULL; public static function foo() { if(NULL === self::$_singletonFoo) { self::$_singletonFoo = new Foo; } return self::$_singletonFoo; } } This is the way I'd do it. It creates the object on demand: Application::foo()->bar(); It's the way I am doing it, it respects OOP principles, it's less code than how you're doing it right now,and the object is created only when the code needs it for the first time. Note: what I've presented is not even a real singleton pattern.
A singleton would allow only one instance of itself by defining the constructor (Foo::__constructor()) as private. It is only a "global" variable available to all "Application" instances. That's why I think its use is valid as it does NOT disregard good OOP principles.
Of course, as anything in the world, this "pattern" should not be overused either! I've seen this being used in many PHP frameworks, Zend Framework and Yii among them. And you should use a framework.
I'm not going to tell you which one. Addendum For the ones among you worrying about TDD, you can still make up some wiring to dependency-inject it. It could look like this: class Application { protected static $_singletonFoo=NULL; protected static $_helperName = 'Foo'; public static function setDefaultHelperName($helperName='Foo') { if(is_string($helperName)) { self::$_helperName = $helperName; } elseif(is_object($helperName)) { self::$_singletonFoo = $helperName; } else { return FALSE; } return TRUE; } public static function foo() { if(NULL === self::$_singletonFoo) { self::$_singletonFoo = new self::$_helperName; } return self::$_singletonFoo; } } There's enough room for improvement.It's just a PoC, use your imagination.
Why do it like that? Well, most of the time the application won't be unit-tested, it will actually be run, hopefully in a production environment. The strength of PHP is its speed.
PHP is NOT and never will be a "clean OOP language", like Java. Within an application, there is only one Application class and only one instance of each of its helpers, at most (as per lazy loading as above). Sure, singletons are bad, but then again, only if they don't adhere to the real world.
In my example, they do. Stereotyped "rules" like "singletons are bad" are the source of evil, they're for lazy people not willing to think for themselves. Yeah, I know, the PHP manifesto is BAD, technically speaking.
Yet it's a successful language, in its hackish way. Addendum One function style: function app($class) { static $refs = array(); //> Dependency injection in case of unit test if (is_object($class)) { $refsget_class($class) = $class; $class = get_class($class); } if (!isset($refs$class)) $refs$class = new $class(); return $refs$class; } //> usage: app('Logger')->doWhatever().
2 Nice approach, and a one-liner too. Good input, thanks! – Pekka Nov 28 '09 at 13:25 2 I downvoted the answer because I believe suggesting the singleton pattern to handle the problem goes against solid OOP principles.
– koen Nov 28 '09 at 16:27 1 @koen: what you're saying is true, generally speaking, BUT as far as I understood his problem, he's talking about helpers for the application, and within an application there's only one ... uhm, application. – Flavius Nov 28 '09 at 17:24 Note: what I've presented is not even a real singleton pattern. A singleton would allow only one instance of a class by defining the constructor as private.It is only a "global" variable available to all "Application" instances.
That's why I think its valid does NOT disregard good OOP principles. Of course, as anything in the world, this "pattern" should not be overused either. – Flavius Nov 28 '09 at 18:21 2 This does indeed make his existing approach much cleaner.
– Daniel Von Fange Nov 28 '09 at 2:29.
The best approach is to have some kind of a container for those resources. Some of the most common ways to implement this container: Singleton Not recommended because it is hard to test and implies a global state. (Singletonitis) Registry Eliminates singletonitis, bug I'd not recommend registry too, because it is a kind of singleton too.(Hard to unit test) Inheritance Pity, there is no multiple inheritance in PHP, so this limits all to the chain.
Dependency injection This is a better approach, but a bigger topic. Traditional The simplest way of doing this is using constructor or setter injection (pass dependency object using setter or in the class constructor). Frameworks You may roll your own dependency injector, or using some of the dependency injection frameworks, eg. Yadif Application resource You may initialize each of your resources in the application bootstrap (which acts as a container), and access them anywhere in app accessing the bootstrap object.
This is the approach implemented in Zend Framework 1. X Resource loader A kind of a static object which loads (creates) needed resource only when needed. This is a very smart approach.
You may see it in action e.g. Implementing Symfony's Dependency Injection component Injection to specific layer The resources are not always needed anywhere in the application. Sometimes you just need them e.g. In the controllers (MV C ). Then you may inject the resources only there.
The common approach to this is using docblock comments to add injection metadata. See my approach to this here: How to use dependency injection in Zend Framework? - Stack Overflow In the end, I'd like to add a note about very important thing here - caching.In general, despite the technique you choose, you should think how the resources will be cached.
The cache will be the resource itself. The applications can be very big, and loading all resources upon each request is very expensive. There are many approaches, including this appserver-in-php - Project Hosting on Google Code.
If you want to make objects globally available, the registry pattern could be interesting for you. For inspiration, have a look at Zend Registry. So also the Registry vs. Singleton question.
If you don't want to use Zend Framework, here is a nice implementation of the registry pattern for PHP5: phpbar. De/w/Registry – Thomas Jan 24 '10 at 8:49 I prefer a typed Registry Pattern, like Registry::GetDatabase("master"); Registry::GetSession($user->SessionKey()); Registry::GetConfig("local"); ... and defining an interface for each type. This way you make sure you don't accidently overwrite a key used for something different (i.e.
You might have a "master Database" and a "master Config". By using Interfaces you make sure that only valid objects are used. Ofc this could also be implemented by using multiple Registry classes but imho a single one is simpler and easier to use but still has the advantages.
– dbemerlin Jan 29 '10 at 13:53 Or of course the one built into PHP - $_GLOBALS – Gnuffo1 Oct 27 '10 at 11:38.
Objects in PHP take up a good amount of memory, as you have probably seen from your unit tests. Therefore it is ideal to destroy un-needed objects as soon as possible to save memory for other processes. With that in mind I find that every object fits one of two molds.1) The object might has many useful methods or needs to be called more than once in which case I implement a singleton/registry: $object = load::singleton('classname'); //or $object = classname::instance(); // which sets self::$instance = $this 2) The object only exists for the life of the method/function calling it in which case a simple creation is beneficial to prevent lingering object references from keeping objects alive too long.
$object = new Class(); Storing temporary objects ANYWHERE might lead to memory leaks because references to them might be forgotten about keeping the object in memory for the rest of the script.
I'd go for function returning initialized objects: A('Users')->getCurrentUser(); In testing environment you can define it to return mock-ups. You can even detect inside who calls the function using debug_backtrace() and return different objects. You can register inside it who wants to get what objects to get some insights what's actually going on inside your program.
Thanks gcb, but the loading of classes is not my concern, my question is of a more architectural nature. – Pekka Jan 29 '10 at 16:37.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.