I know this is a very debated topic among programmers and I already read a lot about the cons and pros about the singleton pattern.
Still I want to ask about the singleton pattern.
I'm creating a small PHP framework and I'm stuck the way I'm handling Cookies in my framework.
Upfront:
The framework provides factory functions for every module so from the outside it is not clear whether the instance is a singleton or not.
Example:
$db = Framework::DB(); // always a new instance
$cookie = Framework::Cookie(); // singleton (maybe?)
My take:
Provide a singleton cookie instance which can be used to mutate cookies (set, delete, get):
class Cookie {
public function set($name, $value) {
}
}
My reasoning is that cookies are a global state and you cannot create a fresh cookie environment - it is always provided by the browser.
For me it makes just no sense to instantiate a new cookie class instance.
But maybe I'm missing something.
Essentially I wonder if there is better solution (without using the singleton pattern) or if that is one of the cases where a singleton actually makes sense.
A Singleton basically means you can only create 1 instance of a class, I personally don't see the point in hard-coding that into a class because generally speaking a class is something created so you can create multiple objects.
For your database example, for most websites only handling 1 database it should be fine. But what if in the future you want to connect to an external database using the same API? Ohh, you cannot because I implemented a singleton interface.
Now lets talk about your cookie example, each website has the ability to store multiple cookies. Why create a singleton out of that? Design that class so that $cookie2 = new Cookie('name') references to the other cookie. Yes, it can all be done with 1 class, a singleton where each time you need to parse a name to determine what cookie to put it in.
There are very few cases a singleton design pattern can be useful, at least in PHP. Most people use a container to store a variable that references to a single instance of a class (basically a singleton). However that container can be changed for another container, perhaps to something like a test environment referring to a different database and a different cookie all while using the same API.
Related
I am facing a dilemma regarding OOP design of my application. Should I make the auth class a singleton or not. I see that kohana framework and zend framework use their auth classes as a singleton. What are the disadvantages of making the authentification class a singleton? What are the pros? Also the application I am building will be an enterprise application and it needs to scale, so will my auth system also scale if it will be a singleton?
Here would be some cons:
extremely hard to test, because code is tied to name of class
introduction of global state
inability to determine causes for an effect - unrelated methods can affect each other
scattering of authentication requests all over codebase
violation of LoD
You might benefit a lot from examining, at what stage and how exactly you authenticate the user ( do not confuse with authorization ). Also, this topic might be of some interest to you.
Update:
Here are few videos you might be interested in:
Clean Code Talks: Unit Testing
Clean Code Talks: Global State and Singletons
Clean Code Talks: Don't Look For Things!
PHP UK Conference 2011: Advanced OO Patterns
Avoid using the singleton and use it only in the case when a hardware has the limitation on one object -> resource per application. If you incorporate the singleton you will unable to exchange the auth class with something else in your system you will be stacked with it. Consider that tomorrow you could receive a new requirement which say you that you need to implement the authentication using a different logic, different connection and so on. Also though about how to test your system after using the singleton how will you mock it??
Don't go for Singleton! It's no better than glorified object-oriented namespace, in fact Singleton almost just as bad as using Global variables and only slightly better than using global function libraries (which in itself is also bad). It's better to send the created object to your classes.
Since PHP 5 objects passed around to other objects are passed by reference by default. They don't create a new instance (unless using clone keyword). This allows any sort of session info to be just passed as an object to other objects that need it.
Best thing I can recommend is make a class 'Session' that carries session specific information. Send this class to your MVC objects. This allows you to test the system without Session being present (or you can create a mockup state for that purpose). While passing one object to another makes them more coupled than ideal, as long as the class is primitive enough it can be easily created in other systems or parts of the app that use the same classes.
It also makes it easier to transfer states or sessions at any given time, even within the same request.
In PHP, the object doesn't stays in the memory once the request is completed.
So even if you make your object as Singleton, every request will have its own instance of that class.
But the the difference will come when object is being accessed multiple times in a single request. In that case, singleton has following advantages:
Prevents creating multiple redundant instances, so lesser memory usage for requests.
Shares the same data across multiple accesses.
Eg: Codeigniter's get_instance function is an implementation of Singleton Concept, whereby only one Codeigniter instance is used in each request.
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 ;)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Who needs singletons?
i was wondering, what are the drawbacks using Singletons in php scripts. I use them alot and i sometimes can't understand criticism of developers. Some examples:
I have a Request class:
Sanitizing POST, GET, COOKIE inputdata and using it instead of the global arrays - strictly and globally. Like
$request = Request::getInstance();
$firstname = $request->post('firstname', $additionalFilters);
There is always only ONE request per request. Why is using singleton in this case a bad idea?
Same for $_SESSION:
I have a Session class (Singleton) which does represent the $_SESSION array because there is only one session and i use it globally.
Database
$mysql = DB::getInstance('mysql', 'dbname'); //pseudo
$sqlite = DB::getInstance('sqlite', 'dbname'); //pseudo
For each type of database, i want only ONE object and never MORE. In my opinion there is otherwise a risk of chaos.
Unique rows
Also i often use classes to represent/use a unique row of a db table.
$article = Article::getInstance($id);
$navigation = Navigation::getInstance($id);
I see only benefits doing it this way. I never want a second object representing a unique row. Why is singleton such a bad idea here?
In fact, most (nearly all) my classes don't have a public constructor but always a static method like getInstance($id) or create() so the class itself handles the possible instances (which doesn't mean they are all singletons by definition)
So my question is: Are there any drawbacks i didn't realize yet. And which concrete scenario's the singleton-doubters thinking of when advise against Singletons.
Edit:
Now, you got a singleton that wraps around the $_POST, but what if you
don't have $_POST, but want to use a file for input instead? In that
case, it would be more convenient if you have an abstract input class,
and instantiate a POSTInput to manage input through posted data.
Ok, valid advantages. I didn't realized that. Especially the point regarding the Request class.
Still i have doubts whether that approach. Assume i have a "Functionality" class which executes a concrete request (like a guestbook component).
Within that class i want to get a sent parameter. So i get my singleton instance of Request
$req = Request::getInstance();
$message = $req->post('message');
This way, only my functionality object cares about a Request class.
When i use the non-singleton approach, i need somehow an additional class/function to manage that every request gets a valid request object. That way my Functionality class doesn't need to know about that managing class but in my opinion there still arises a dependence/problem: Everytime i create an instace of an Functionality object there is a chance that i forget to set a request object.
Surely i can define a non-optional parameter when creating a functionality. But that leads to a parameter overkill altogether at some time. Or not?
Singletons (and static classes, to which the same story largely applies) are not bad per se, but they introduce dependencies that you may not want.
Now, you got a singleton that wraps around the $_POST, but what if you don't have $_POST, but want to use a file for input instead? In that case, it would be more convenient if you have an abstract input class, and instantiate a POSTInput to manage input through posted data.
If you want to get input from a file, or even (for whatever reason) want to mimic (or replay) multiple requests based on input from a database table, you can still do this, without altering any code, except the part that instantiates the class.
Same applies to other classes too. You don't want your whole application to talk to this MySQL singleton.. What if you need to connect to two MySQL databases? What if you need to switch to WhatEverSQL?.. Make abstracts for these kinds of classes, and override them to implement specific technologies.
I do not think singletons should have as bad press they do in a request-based architecture such as PHP or ASP.NET (or whatever you want). Essentially, in a regular program the life-time of that singleton can be as many months or years as the program is running:
int main()
{
while(dont_exit)
{
// do stuff
Singleton& mySingleton = Singleton::getInstance();
// use it
}
return 0;
}
Apart from being little more than a global variable, it is very hard to replace that singleton with, perhaps, a singleton that might be useful in unit-testing. The amount of code that could depend on it, in potentially hundreds of source files tightly couples the use of that singleton to the entire program.
That said, in the case of request-based scenarios such as your PHP page, or an ASP.NET page, all your callable code is effectively wrapped in a function call anyway. Again, they are obfuscating a global variable (but within the context of the request) with safe-guards against being created more than once.
But still, I advocate against their use. Why? Because even in the context of your single request, everything is reliant and tightly coupled to that instance. What happens when you want to test a different scenario with a different request object? Assuming you coded using includes, you now have to go and modify every single instance of that call. If you had passed a reference to a pre-constructed Request class, you can now do cool stuff, such as provide mock unit-testing version of your class, by simply changing what gets passed down to the other functions. You've also de-coupled everything from using this universal Request object.
I know that Singleton pattern is bad because it uses global state. But in most applications, you need to have a single instance of a class, like a database connection.
So I designed my Database object without using the singleton pattern but I instanciate it only once.
My question is, how can I access my object in the low level classes (deep in the object graph) without passing it all over the place?
Let's say I have an application controller which instanciates (ask a factory to instanciate it actually) a page controller which instaciates a User model which requires the database object.
Neither my app controller nor my page controller need to know about the database object but the User class does. How am I suppose to pass the object to it?
Thanks for your time!
Consider using a global container:
You register the objects that are indeed relevant to the several subsystems of the application.
You then request that container those objects.
This approach is very popular in dependency injection frameworks (see Symfony DI, Yadif).
Singleton is bad, no doubt about it.
In the case you describe, the database object is an implementation detail of the User object. The layers above need only know about the User, not the database object.
This becomes much more apparent if you hide the user object behind an interface and only consume that interface from the layers above.
So the page controller should deal only with the interface, not the concrete class that depends on the database object, but how does in create new instances? It uses an injected Abstract Factory to create instances of the interface. It can deal with any implementation of that interface, not only the one that relies on a database object.
Once more, you hide the page controller behind an interface. This means that the concrete implementation's reliance on the Abstract Factory becomes another implementation detail. The Application Controller only consumes the page controller interface.
You can keep wrapping objects like that like without ever needing to pass around instances. Only in the Composition Root do you need to wire all dependencies together.
See here for a related answer with examples in C#: Is it better to create a singleton to access unity container or pass it through the application?
The way I've always accomplished this is to implement a static getInstance function that will return a reference to the single instance of that class. As long as you make sure that the only way you access the object is through that method, you can still ensure that you only have one instance of the singleton. For example:
class deeply_nested_class {
public function some_function() {
$singleton = Singleton::getInstance();
}
}
There are two main objects involved in loading/saving a user using the database: the user and the repository.
You seem to have implemented the functionality on the User, but I think it belongs on the Repository. You should pass the user to the Repository to save it.
But, how do you get hold of the Repository? This is created once at the top level and passed into services that need it.
The construction dependency graph and the call dependency graph are not the same thing.
Given the example you outlined, you are almost there. You are already using a factory to instantiate your page controller, but your page controller is instantiating the users directly and as your User needs to know the database.
What you want to do is use a factory to instantiate your User objects. That way the factory can know about the database and can create User instances which know about it too. You will probably be better off making interfaces for all the dependencies, which will help with testing and will mean your code is nicely decoupled.
Create an IUserFactory which creates IUser implementations and pass this into your PageControllerFactory, then your ApplicationController only needs to know about the PageControllerFactory, it doesn't need to know anything about the IUserFactory or the database.
Then in your application start up you can create all of your dependencies and inject them in to each other through the constructors.
I'm currently working on an oophp application. I have a site class which will contain all of the configuration settings for the app. Originally, I was going to use the singleton pattern to allow each object to reference a single instance of the site object, however mainly due to testing issues involved in this pattern, I've decided to try a different approach.
I would like to make the site class the main parent class in my app and call it's constructor from within the constructors of the child classes, in order to make all the properties available whenever needed.
When run for the first time, the class will only contain the db details for the app. To get the remaining values a query must be performed using the db details. However, any subsequent instances will be clones of the original (with all values). I may also set a Boolean flag to perform the query again a completely new instance is required.
Would this be a viable alternative to the singleton and would it solve the testing issues it causes? This is all theory atm, I haven't started to code anything yet,
Any thoughts or advice greatly appreciated.
Thanks.
I think a better way is to have an 'configuration' object that will get passed to the constructors of all your other classes. So, almost something like a singleton, except it's explicitly created and passed only to classes that need it. This approach is usually called dependency injection.
After trying many different techniques, what I have found functional and reliable is this method:
Use a bootstrap, or initialization file. It is located in the ROOT of the site with the proper permission and safe-guards against direct access.
All pages in the site first include this file. Within it, I create all my global objects (settings, user), and reference them from there.
For example:
// OBJECT CREATION
$Config = new Configuration();
$User = new User();
Then within classes that require these objects:
public function __construct($id = NULL) {
global $Config; // DEPENDENCY INJECTION SOUNDS LIKE AN ADDICTION!
if($Config->allow_something) {
$this->can_do_something = true;
}
if(NULL !== $id) {
$this->load_record($id);
}
}
Notice that I just access these global objects from within the class, and how I don't have to include the object variables as the first constructor parameter each and every time. That gets old.
Also, having a static Database class has been very helpful. There are no objects I have to worry about passing, I can just call $row = DB::select_row($sql_statement);; check out the PhpConsole class.
UPDATE
Thanks for the upvote, whoever did that. It has called attention to the fact that my answer is not something I am proud of. While it might help the OP accomplish what they wanted, it is NOT a good practice.
Passing objects to new object constructors is a good practice (dependency injection), and while "inconvenient," as with other things in life, the extra effort is worth it.
The only redeeming part of my answer is use of the facade pattern (eg. DB::select_row()). This is not necessarily a singleton (something the OP wanted to avoid), and gives you an opportunity to present a slimmed down interface.
Laravel is a modern PHP framework that uses dependency injection and facades, among other proven design patterns. I suggest that any novice developer review these and other such design practices thoroughly.