I've got this Config-class that I use in my PHP5 application to load & parse my static config. This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
But now as I need to set/make changes in my Config during runtime at one place, my changes aren't reflected globally and being far from a specialist with the use of the static modifier in PHP, I need to ask:
What is the best way to ensure that changes to the properties in my Config-class are reflected throughout my application without making the class into a singleton? Can I just make the variable holding the config data static?
This far I've managed to keep the class from being a singleton/registry and instead passed the instance of the Config class around to wherever it's needed with the help of Dependency injection.
If you pass the same instance of your Config class to every part of your application and you change a setting it should be reflected everywhere else.
In case you are creating multiple objects of the class (and parse that config file every time?!) you might want to stop doing that. It's possibly wasteful and I'd say it is confusing.
So if you create only one and pass that around everything should be fine.
Under the assumption that you create multiple instances of the object that only should exist once:
If you are able to "fix" your architecture to allow you to do that: Do so.
If you can't to that... well.. creating a static property to hold your values in a class that you can have multiple instances off is, at least in my book, a major wtf factor. If you can't fix (meaning it's to much off a hassle to do so) just "break" it in an expected way so other people don't trip over it.
I'd rather have a singleton than something that creates all the issues with singletons and also lies about being a wrapper for a global variable.
Blindly avoiding design patterns because you hear on Internet forums that they're bad is about as much an anti-pattern as singletons are in general. If a tool is right for a job, then it's right.
Look at your question, you're trying to emulate singletons through a complex multi-update system for God's sakes... And just so you know, making a class static is essentially turning it into a singleton, albeit an insecure one that can be overwritten at any time.
TL;DR: Think for yourself and use the right tools; make your config class a singleton.
Related
Why should I use Zend_Registry instead of the Singleton pattern?
My coworker and me recently had a discussion about this. His point was that we should use Zend_Registry for all consistent objects, but I wanted to use the singleton pattern, since Zend_Registry just does the same, but wrapped.
I have a problem with code like this:
$list = Zend_Registry::get('database')->getList($sql);
Since theres a chance that database isn't in Zend_Registry. In cases of lazy loading, I would have to make my own registry with information about specific objects in my system. Like if the database takes specific parameters on loadtime, then it would have to know this.
I would instead use getInstance and then all the code would reside in the same object. Does that make sense?
Even though you phrased your question as an either/or, might I suggest a third alternative?
I try to avoid both singletons and Zend_Registry wherever possible, since they function, in effect, as globals. When a segment of code can reach into the global ether - via a call to a singleton or a global registry - to get something it needs, it creates a hidden - or at least, a non-explicit - dependency that makes things harder to debug and unit-test.
In contrast, I try to follow dependency injection advice, paraphrased as: "Give a component what it needs. Don't make it find what it needs."
I find that for most entities for which I might feel I need a registry/singleton - db connections, loggers, etc - I can create them at Bootstrap, store them in the Bootstrap registry and inject them into my controllers, usually during init() using $this->getInvokeArg('bootstrap')->getResource('myResource'). Only controllers reach back into the Bootstrap. Then, any models or services that need these dependencies get them passed-in explicitly by the controller, either via constructor or by setter injection.
A hybrid approach to which I do sometimes fall back is to design my service/model classes with getters/setters for these dependencies - getDbAdapter() and setDbAdapter(); getLogger() and setLogger(), etc. The getter lazy-loads from the global registry - whether some singleton or by Zend_Registry, throwing exceptions when they are not where I expect them to be. In that sense, it is similar to what you are suggesting. It does violate the purist dependency injection philosophy. But at least the presence of the getter/setter methods explicitly demonstrates that there is a dependency and allows me to mock it out or to provide non-default implementations.
It does for simple blog or something. Otherwise you're stuck with only one DB instance. And that's NOT what you want in the long run. You may want to connect to other server (to log errors to central db, to import products from someone, ...) or connect as different user (for security reasons - you don't want your API to have access to admin_users table, but you still need to connect to it to check if user is valid in the first place).
You can do one-purpose registers (My_Db_Admin, My_Db_ReadOnly, ...) but that does not make much sense to me. Using registry you're not stuck with one instance. You can create one outside registry and work with it for a while and then trash it ;)
Before I begin, this framework is not meant to compete with Zend, Symfony, Cake or any other framework. It is primarily a personal project so that I may test out some PHP 5.3 goodies, experience new techniques and gives me the chance to try things under my idea. I am also trying to make this framework as lightweight as possible, and reduce the amount of unncessary getters and setters. Now for the problem at hand.
A bulk of the framework is done, primarily all the core classes required for it to run. The problem arises on the entry point of the application. I want the whole application to be run through a single core object which branches out. The core object will be extended with classes to manage environments, configuration, registry, autoloading, routing, etc, etc. You can see this "core" object below, it is aptly called Application.
https://github.com/titon/titon/blob/42c88e36c29e3d8c697306fe68be18b3a8fd2e70/titon/source/Infrastructure.php
$app = new \titon\source\core\Application();
The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:
(I cant post more than 1 link, so please go to the following directories on Github. /app/config/Setup.php and /app/modules/core/Bootstrap.php)
$app->environment->current();
$app->loader->includePath(array(__DIR__));
$app->registry->factory('titon\source\system\Controller');
But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.
public function foobar() {
global $app; // Eww
}
But I also do not want to use static classes, as I was trying to go for a more OOP approach. The only solutions I can think of is using a static class property to hold the Application instance and access that everywhere, but I do not like that. Or I can pass the object down to its children over and over again, but again, not a fan.
Core::$app->router->detect(); // Meh
$this->setApplication($this); // Mehher
I was curious how Zend and Symfony approached this problem. But after looking through their source code, I could not backwards engineer and determine the correct entry point. Furthermore, it seemed Zend would created global variables all over (Zend_Config, etc), but I would prefer to have a managing object. Symfony 2.0, I just got lost. As for Cake, Solar, Fuel, it seems they are using static classes for these kind of objects.
Now my primary question is, how would you solve this? I would like to keep a single object to instantiate and be accessible everywhere, but it doesn't seem like an easy thing to handle. I am willing to rewrite a lot of the framework if need be.
The idea was that from anywhere in the application, you can access the core objects through this $app variable. Example:
...
But now we get into the problem of global variables, which I do not want to use. I also like to try and avoid Singletons.
That seems like a contradiction to me.
Do you know why you don't want any global variables? Is it because you read somewhere that global variables are a bad thing?
Conversely, do you know why you want a central object that is available from anywhere in your application?
Follow Up:
In case it wasn't clear, those were meant as rhetorical questions. From an architectural viewpoint, global variables (in any shape) are expensive. Some say evil. I think that's missing the point slightly - You need some amount of global variables in any application (At least one). To further muddy the waters, "global" is really a relative thing; It is much more meaningful to consider variables as having varying scopes, where global is on one extreme of the continuum and local, temporary variable at the other. If you have a single object containing all your other objects, then I would consider each of these variables as being effectively global variables, even though they may not be so in a technical sense. Think a bit about that.
As for a silver bullet, you could take a look at dependency injection. This is an approach to avoiding global variables that works, but has some cost in the form of complexity.
One of PHP's old unresolved issues: One can't define superglobals, without using a extension like runkit.
I usually solve this with a pseudo-Registry, i.e. I define a class R with all variables I want to make global defined as public static $var. I know, this is probably not the vanilla-OOP approach, but it serves well. R::$var is as short as it get, I think. Everything else, like dependency injection ($this->var) or singleton (R::getVar()), is longer.
The best solution to avoid global variables is dependency injection. You'll probably need to create some container. Look at the Symfony components library.
You may also try registry pattern.
In a theoretical database access class, I found that there are quite a few helper functions that I use in the class, which have nothing to do the class's instance (and others, that could be manipulated to be unrelated to the class's instance using dependency injection).
For example, I have a function that gets a string between two other strings in a variable. I've been thinking of moving that to a String_Helper class, or something of the sort. This function has already been made static.
Also, I have a function that queries a database, query($sql). The connection details are provided by the instance, but I've been considering making it static, and using query($sql, $connection). Developers would then be able to call it statically and not need to instantiate the database class at all.
For me, the questions are:
Is it worth it to do something like this? Functions like the query function make me wonder if this is not just me trying to make everything as static as possible, without any real need to. Under what circumstances would you consider this useful?
I know static functions are harder to test, but if I make sure that their code is completely dependency free (or uses dependency injection where necessary), then they're just as easy to test as everything else, surely?
It isn't a concern at the moment, but if, in the future, I decided to extend the classes with the static functions, it would be impossible for me to make the current code use my extended functions. I've thought of Singletons, but the same problem arises: the code would be calling Singleton_Class::getInstance(), and not My_Extended_Singleton_Class::getInstance(). Dependency Injection seems to be the only way to solve this issue, but it might lead to a clunkier API, as every dependency has to be given to an object on __construct().
I have a container class, which holds certain pieces of information statically so that they can be accessed anywhere in the script (global scope). If I can't use static functions or singletons, a class that contained instances of different variables would be great. One could use for example Container::$objects['MyClass'] = $MyClass_object;, and then the rest of the code could just access Container::$objects['MyClass']. If I extended the MyClass class, I could use Container::$objects['MyClass'] = $MyExtendedClass_object;, and the code that used Container::$objects['MyClass'] would use MyExtendedClass, rather than MyClass. This is by far the best way to do it, in my opinion, but I'd like to know what you think about it.
Ok, let me answer these one by one...
1. Is it worth doing something like this
Yes and no. Splitting out the helper functions into their own classes is a good idea. It keeps the "scope" of each of the classes rigidly defined, and you don't get creap. However, don't make a method static just because you can. The query method is there to make your life easier by managing the connection, so why would you want to lose that benefit?
2. They are harder to test
They are not harder to test. Static methods that depend on state are harder to test (that access static member variables or global variables). But static methods in general are just as easy to test as instance methods (in fact, they can be easier since you don't need to worry about instantiation).
3. Extending the classes
This is a valid concern. If you put String_Helper::foo() in the class itself, you'll run into issues. But an option would be to set the name of the string helper as a class variable. So you could then do {$this->stringHelper}::foo() (note, PHP 5.3 only). That way to override the class, all you need to do is change the string helper class in that instance. The Lithium framework does this a lot...
4. Global Registry
I would stay away from this. You're basically just making every class a singleton without enforcing it. Testing will be a nightmare since you're now dependent on global scope. Instead, I'd create a registry object and pass it to classes via the constructor (Dependency Injection). You still accomplish the same thing since you have a store for the objects/classes, but you're no longer dependent on a global scope. This makes testing much easier.
In general
When you're looking at doing things like this, I like to stop when I hit questions like this. Stop and sit down and think *What actual problem am I trying to solve?". Enumerate the problem explicitly. Then pull our your supposed solutions and see if they actually solve them. If they do, then think about the future and if those solutions are really maintainable in the long run (Both from a bug fix standpoint, and with respect to feature additions). Only if you're happy with both of those answers should you even consider doing it. Oh, and also remember to keep it simple. Programming is not about making the most complex, most clever or most amazing solution. It's about making the simplest solution that solves the problem...
I hope that helps...
Good Luck!
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
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.
Look into the factory pattern and dependency injection.
http://www.potstuck.com/2009/01/08/php-dependency-injection/
You can't extend a singleton class. Remember in singleton class we make the constructor private so if a constructor is private than how could you extend this class? We all know what we create an object of a class we call its constructor and in child class constructor it implicitly called the parent constructor. So in this scenario a private constructor can't be called in the child class.
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.
From my basic understanding in Object Oriented coding, PHP in my case, you want to make all your classes pretty much independent of one another. I have just started my object oriented application so it is a great time for me to make changes in it's early stages.
Here is my situation where I break this rule or whatever you want to call it.
I have a sessions class that has a set method which lets me set variables to a php session and I have a view method which let's me view the value of a value that has already been set using the set method. So far it probably sounds OK but then on every page of my site I need to access session data or the session objects I should say. But then besides every page using the session objects, I also use them in all my classes that need the session value. I believe this is where I have messed up, because now all these other classes rely on the session class.
Any ideas on if this is wrong and if it is, what are some ways I can avoid it but still have access to the session data in the other classes and still have my classes be portable plug-n-play into other future applications?
This kind of relationship is called dependencies or coupling. You generally want to reduce coupling in any application (Object oriented or not). Just how to do it is perhaps the most important skill of a programmer, and can't really be summarised into a few rules.
However, at the most basic, you should try to distinguish between essential dependencies and accidental dependencies. The former is an un-solveable problem, so you shouldn't try. For example, if all your pages need access to the session, then you really can't help giving them that. But if they only need it some times, than you could try to factor your application so that this is addressed.
Another important point is to minimise the interfaces between components. If x is a subset of X and Y relies on x, then you shouldn't pass X. This is often a place where there is room for improvement.
Think about what those other classes need in order to function in terms of your domain model. Session data is an implementation detail that shouldn't affect how you design your other classes. The session object might have 100 properties, but not every class needs all 100 of those properties to work. They don't need to know if that data was persisted in sessions, cookies, flat-files, databases, or on a satellite outside earth.
A great resource I've found useful while designing classes is this book, and specifically chapter 6, "Working Classes" for your question.
You could add one level of abstraction making it WorkingClass > StoringMapper > Session, with WorkingClass only calling StoringMapper. As such, you could easily "map" the storing process to any other class than Session (for example DatabaseSession) without any changes to WorkingClass.
I've written some code for it in response to another question: Advice on framework design
Generally, one class using another is pure basic OO and what you'll want. Using Interfaces is a way to have your concrete logic isolated while letting other classes use this component in a uniform way. A simple and common way is to use a Factory or Abstract Factory instead of directly calling constructors. You should also have a look at the Inversion of Control and Dependency Injection (DI) paradigms. Here's a rudimentary example that could help you with your problem (but be aware, the author mixes up between Factories and DI).
A not to complex solution would be to extract an interface from your Session class. Think of what a caller would need from a session object. Then realize the interface in your class. You'll maybe want to make this class a Singleton (a class for which only one realization exists at runtime). Then, create a factory that instanciates your script's components. Pass the session instance to the components in the factoring method.