2

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?

Mythriel
  • 1,322
  • 5
  • 23
  • 44
  • 1
    Probably a question for http://programmers.stackexchange.com/ – DaveRandom Mar 30 '12 at 08:59
  • 2
    Are there any pros? Singletons are just another fancy word for globals. Which you should know are bad. – PeeHaa Mar 30 '12 at 09:00
  • yes I understand, but I am making some case studies and try to understand why frameworks like zend and kohana use singleton for their auth class – Mythriel Mar 30 '12 at 09:11
  • 1
    Because they don't follow best practices. – PeeHaa Mar 30 '12 at 09:13
  • 3
    Zend is a bad example for anything, it's a very bloated framework and loses more users every day than gains. Zend is one of the biggest hypocrits of PHP world, they push for standardization and good practices but Zend framework itself is very loose when following all but superficial standards. – kingmaple Mar 30 '12 at 09:14
  • @Mythriel: frankly speaking there is nothing wrong with Singleton and its a good concept. If someone says, that zend framework doesn't follows best practices, well, then they surely can't digest OOP designs well. – linuxeasy Mar 30 '12 at 09:14
  • @linuxeasy , if you scroll down, you will notice the *"Clean Code Talks: Global State and Singletons"* link. Click on it. This might clear some things up. – tereško Mar 30 '12 at 10:02

4 Answers4

3

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:

Community
  • 1
  • 1
tereško
  • 56,151
  • 24
  • 92
  • 147
  • how is code tied to a name of a class? when you can use a factory method which can return reference of your singleton class and then that reference can be used with any name whatsoever you like? – linuxeasy Mar 30 '12 at 09:15
  • 2
    @linuxeasy , the fact that you even use factory method pattern is bind you to the name of some class. When you write `Auth::getInstance()`, you couple your code to the class named "Auth". Of course you could use an abstract factory, but if you pass an instance of factory class around your code, then it losses the the point of having singleton. A factory itself can ensure that there is only one instance of object. – tereško Mar 30 '12 at 09:25
  • Give this guy upvotes. We need sanity in this war against Singletons. – kingmaple Mar 30 '12 at 09:28
  • 1
    @linuxeasy , the way you usually deal with singletons in testing is via autoloading and/or creating an alias for a class. But it is extremely convoluted way, because you have to test this way not only the singleton, but also all the classes which are coupled to it. – tereško Mar 30 '12 at 09:28
  • your `Auth::getInstance()` can remain in a plain function &get_instance() independent of class name right? and what do you mean by saying **if you pass an instance of factory class around your code, then it losses the the point of having singleton** ?? how does this makes it lose point of singleton? – linuxeasy Mar 30 '12 at 09:29
  • @kristovaher: Lol.. also add me to downvotes in your war against singletons :D, you find it hard to design a good singleton? :P – linuxeasy Mar 30 '12 at 09:31
  • @linuxeasy , singletons main purpose is to ensure that there is only **one** instance of an object. An abstract factory does the same thing without relaying on global state. – tereško Mar 30 '12 at 09:33
  • 1
    @linuxeasy , a global scope function is not a solution, because testing relies on polymorphism. To test a unite of code, you have to isolate it. This isolation is accomplished through injection of [mock object](http://en.wikipedia.org/wiki/Mock_object). – tereško Mar 30 '12 at 09:35
  • 1
    @linuxeasy , since php5 , you do not need to pass objects through references. In PHP4 you wrote: `$foo = & $bar_object;`. If you do the same in PHP5, you are increasing the memory usage of script. In PHP5 we accomplish the same with `$foo = $bar_object;`. This is because only *object handler* gets passed around. – tereško Mar 30 '12 at 09:37
  • @tereško: where its logical, not to use Singleton, do not use it. Where it is logical to use singleton, there's no harm in using it. Now dont keep me such examples. I am not saying about writing everything in singleton that would harm your unit tests, but where there are really large objects, and multiple instances of those object could create scalability problems, there's no harm in using singletons! – linuxeasy Mar 30 '12 at 09:38
  • @linuxeasy - Your argument is about as good as some blokes argument would be for the use of global variables and functions. Singleton is, in essence, a combination of these two. **And not using Singletons will not cause scalability problems!** – kingmaple Mar 30 '12 at 09:38
  • @kristovaher: whatever my argument be, but yours is one of the unique argument I have seen on SO. your lines lol *cumon on give this guy upvotes, for my personal hate towards singletons* :D – linuxeasy Mar 30 '12 at 09:40
  • @linuxeasy , in OOP there is no *logical* place to use a singleton. The singleton itself is an artifact of procedural programing paradigm. Singleton effectively create a global variable using notation which mimics OO notation. – tereško Mar 30 '12 at 09:41
  • @tereško - I am not sure linuxeasy is open for these arguments. I just hope that the discussion here has been good enough to convince others who might be reading this and don't know about the flaws of Singletons. – kingmaple Mar 30 '12 at 09:45
  • I don't understand why it violates LOD? because the auth singleton class would have a single responsability – Mythriel Mar 30 '12 at 10:23
  • @Mythriel , violation happens not inside the singleton, but when any other class instance uses it. – tereško Mar 30 '12 at 10:24
  • why should other classes use the auth object? the auth object should be used in my controllers or action helpers or libraries if i make any, i would not couple with my model classes – Mythriel Mar 30 '12 at 10:41
  • @Mythriel , controllers are usually classes. – tereško Mar 30 '12 at 10:47
  • yes i know...but i wouldn't tie my auth class to my domain model, so having it coupled in the application layer is not that bad, or is it?..what about auth as a service? a service class to handle auth – Mythriel Mar 30 '12 at 10:55
  • @Mythriel , *services* (authentication, mailer .. others) are actually thing of a [model layer](http://martinfowler.com/eaaCatalog/serviceLayer.html). Anyway, i do not understand why you are tying to prove that authentication as a singleton is a good thing. Hell .. how it even gets to your controllers? Shouldn't you check users authorization before you even let them "inside" controller ? And authorization depends on authentication .. which makes it even earlier concern. – tereško Mar 30 '12 at 11:01
  • i am not trying to prove that singletons are good...they are not..only want to make a good auth class for my application...and authorization and authentication are 2 different classes with different roles – Mythriel Mar 30 '12 at 11:11
0

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??

AlexTheo
  • 3,747
  • 1
  • 19
  • 32
0

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.

kingmaple
  • 3,902
  • 5
  • 27
  • 42
-3

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.

linuxeasy
  • 5,237
  • 6
  • 29
  • 38
  • How? Since if you create multiple objects and add a specific object (like Session) to them, then it doesn't create instances of those objects. It passes them by reference by default. It uses the very same object unless you clone it. I don't see how not using Singleton will demand more memory at all. – kingmaple Mar 30 '12 at 09:10
  • 1
    please , do not hold up CodeIgniter as an example for good development practices – tereško Mar 30 '12 at 09:10
  • @tereško: and why do you think so? – linuxeasy Mar 30 '12 at 09:11
  • @kristovaher: Well, when you are creating objects using `new` you a creating a complete instance, whereas if you are using a Singleton, a single instance remains, and that's only Singleton saves memory. – linuxeasy Mar 30 '12 at 09:12
  • @linuxeasy , because i have read the source of CI .. have you ? – tereško Mar 30 '12 at 09:14
  • 2
    @linuxeasy - then you don't know how non-Singleton frameworks are designed. They pass the object to newly created objects instead of using 'new' (I don't know who would design an OOP system like that anyway, new should never be used unless in either bootstrap or through object factory). They are passed by reference, taking no more memory and has none of the flaws that using Singletons have. And they are easy to test. – kingmaple Mar 30 '12 at 09:17
  • @tereško: Surely I have read the source of CI too, and I will like you to put down, what so wrong you found in the soucecode of CI? and was it you the only person to read the CI source in this world? since many companies use CI for a very thin framework it gives. – linuxeasy Mar 30 '12 at 09:17
  • @kristovaher: The talk here is about usage of singleton. If your OOP system is already designed to return references to your object, then your OOP system uses the concept of Singleton + Factory method itself. Now what are you trying to prove? when your example is itself of a singleton? – linuxeasy Mar 30 '12 at 09:20
  • @linuxeasy Factory method does not assume a Singleton. I can test the system with mock classes and I can have multiple instances of the Session object in my system. It is not possible with Singleton. It's almost amusing how difficult for you seems to be to understand that. – kingmaple Mar 30 '12 at 09:26