views:

294

answers:

3

I have am working on a web application that makes use of helper classes. These classes hold functions to various operation such as form handling.

Sometimes I need these classes at more than one spot in my application, The way I do it now is to make a new Object. I can't pass the variable, this will be too much work.

I was wondering of using singleton classes for this. This way I am sure only one instance is running at a time.

My question however is when I use this pattern, should I make a singleton class for all the objects, this would b a lot of code replication.

Could I instead make a super class of superHelper, which is a singleton class, and then let every helper extend it.

Would this sort of set up work, or is there another alternative?

And if it works, does someone have any suggestions on how to code such a superHelper class.

Thank you guys

A: 

While sometimes necessary, singletons are evil (because they're global state). Try to avoid them if you can help it.

EDIT: If you can't avoid singletons, at least parameterise the reference to that state. In other words, in a class, pass in the singleton to its constructor or those methods that use the singleton.

Simply making references all over your codebase to your singleton will compromise your ability to test classes in isolation.

If your singleton's stateful, your tests will suddenly become stateful, and your tests can start "cascade failing" because their preconditions become corrupted by earlier tests failing.

Frank Shearar
A comment explaining the downvote would be appreciated.
Frank Shearar
I did not downvote. I think all responses are good concerning this, as I am not sure to use the singleton patern in the first place.
Saif Bechan
A: 

I can't pass the variable, this will be too much work.

Are you sure though? People tend to overestimate the effort of passing around dependencies. If you do it in the constructor, it's usually fairly simple to do.

That said, you can put shared functionality in the global scope, in different ways in php. The simplest is to use a global function. Eg. a function that doesn't belong to any class. Another option is to use a static class method. These two a very similar; except for their syntax, they essentially have the same properties. A slightly looser coupled solution is to put the functionality as a method on an (abstract) base class, that your concrete class extends from. This shares the functionality between all child classes.

Common for the above-mentioned solutions is that they have a compile time coupling. You can't change the dependency at run time, which makes your application rather rigid. Their main benefit is the low level of complexity they carry.

If you want a looser coupled application, you can try to replace the hard dependency with a variable, to give a level of indirection. The simples is to create an object and make this shared globally throughout the application. There are a number of ways to do this in PHP, such as a singleton or simply a variable in the global scope (You can access this with the global keyword, or through the $GLOBALS array).

While global variables offer a level of indirection, they also tend to introduce a lot of complexity, since they make it very hard to figure out which parts of the application that depends on each other. For this reason, they are often avoided by experienced programmers. This is especially true if the variable has state; The problem is less prevalent if the shared object is stateless.

The only way to avoid the perils of global variables, is to use local variables instead. Eg. To pass the dependencies around. This can be a bit of a hassle, but in my experience it's often not as big a problem as it's made out to be. At least, the benefits often outweigh the problems. That said, there are techniques to easy the pain; Notably dependency injection containers, which are automatic factories that take care of all the wiring for you. They come with their own level of complexity though, but for larger applications they can certainly be a good solution.

troelskn
Thank you for the response, i understand the upside and downside for each of point. I will try to just pass the helpers around in local variables.
Saif Bechan
A: 

Look into the factory pattern and dependency injection.

http://www.potstuck.com/2009/01/08/php-dependency-injection/

Hans