SitePoint Sponsor

User Tag List

Results 1 to 25 of 25
  1. #1
    SitePoint Zealot johno's Avatar
    Join Date
    Sep 2003
    Location
    Bratislava, Slovakia
    Posts
    184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Monostate vs. Singleton pattern in PHP

    Hi everyone,

    I'm new to patterns but I just don't get why is the usage of Singletons in PHP so great. I can understand why to use them in Java, but PHP? Isn't a simple global variable the same?

    For example imagine a Singleton DB layer usage.
    PHP Code:
    function fnc1(){
       
    $db DBSingleton->getInstance();
       
    $rows $db->getAll(...);
       
    // ...
    }

    function 
    fnc2(){
       
    $db DBSingleton->getInstance();
       
    $col $db->getOne(...);
       
    $rows $db->getAll(...);
       
    // ...

    I've just don't see the difference and/or advatage in ease of use, flexibility, speed or code cleanliness from doing the simpliest thing
    PHP Code:
    function fnc1(){
       global 
    $db;
       
    $rows $db->getAll(...);
       
    // ...
    }

    function 
    fnc2(){
       global 
    $db;
       
    $col $db->getOne(...);
       
    $rows $db->getAll(...);
       
    // ...

    I'm using something different, a simple class for PEAR::DB abstraction layer. I'm using it over half a year but yesterday i've figured out that it is in fact a Monostate pattern.

    PHP Code:
    function fnc1(){
       
    $rows SQL::getAll(...);
       
    // ...
    }

    function 
    fnc2(){
       
    $col SQL::getOne(...);
       
    $rows SQL::getAll(...);
       
    // ...

    No global, no singleton and simplier code. So why use Singletons at all?
    Annotations support for PHP5
    TC/OPT™ Group Leader

  2. #2
    SitePoint Enthusiast feti's Avatar
    Join Date
    Jun 2004
    Location
    Northeastern Ohio
    Posts
    42
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh, I'd point my finger to efficiency. In order to appreciate how things work when they're done properly and to understand them, understanding the very basics of computers is a necessity. I'd suggest picking up a C book or ASM if you've got a bit of time. And while you're at it, go pick up the Pragmatic Programmer.

    I know this isn't the answer you wanted. And I probably sound like a jerk. But there comes a time when people that call themselves programmers stop being lazy and be so quick to question why, why, why, when they should take that time to understand and read.
    feti
    Mojavi Project - Mojavi 3.0.0-dev available now!

  3. #3
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    One of the reasons for using a singleton is not to use it - so to say.
    The monostate (or static class) is actually a procedural call in disguise. That is to say there is no real structural difference between this expression :
    DB::SomeMethod()
    and this one :
    DB_SomeMethod().

    If you work with a OO code-structure, this is a conflict since you would introduce procedural code into the OO code. Using a Singleton instead gets you back on the pure OO track :
    $db =& DB::GetSingleton(); $db->someMethod()

    Now you may argue that it's ridiculous to go through all that trouble just to suit formalities, but there is one added benifit of using Singletons.
    If you should ever need to have more than one instance of the object in mind, you will need to make radical changes to all code relying on it if you used the static-class-approach - However if you did in fact use a Singleton in the first place, all you have to change is the places where you use $db =& DB::GetSingleton();

  4. #4
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by feti
    Oh, I'd point my finger to efficiency.
    Which of the three solutions would you call the most "efficient"? And do you mean efficient in terms of execution or development time? (hopefully both...)

    Douglas.
    Hello World

  5. #5
    SitePoint Zealot johno's Avatar
    Join Date
    Sep 2003
    Location
    Bratislava, Slovakia
    Posts
    184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    The monostate (or static class) is actually a procedural call in disguise. That is to say there is no real structural difference between this expression :
    DB::SomeMethod()
    and this one :
    DB_SomeMethod().
    If you are using static attributes I think there is a little difference.

    Quote Originally Posted by kyberfabrikken
    If you work with a OO code-structure, this is a conflict since you would introduce procedural code into the OO code. Using a Singleton instead gets you back on the pure OO track :
    $db =& DB::GetSingleton(); $db->someMethod()
    Hmm, I don't think this violates pure OO coding style much more than some if() then else, foreach() and while(){} code.
    Quote Originally Posted by kyberfabrikken
    Now you may argue that it's ridiculous to go through all that trouble just to suit formalities, but there is one added benifit of using Singletons.
    If you should ever need to have more than one instance of the object in mind, you will need to make radical changes to all code relying on it if you used the static-class-approach - However if you did in fact use a Singleton in the first place, all you have to change is the places where you use $db =& DB::GetSingleton();
    That's a good point, but again why not to use global? I know that globals are evil, but in this example I can see no difference between them and Singletons.
    Annotations support for PHP5
    TC/OPT™ Group Leader

  6. #6
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you are using static attributes I think there is a little difference.
    No comprendes

    Hmm, I don't think this violates pure OO coding style much more than some if() then else, foreach() and while(){} code.
    Using global functions (witch it is) is not good OO. Using basic control-structures is part of the language syntax whether you write in an objectoriented or procedural paradigm.

    I know that globals are evil, but in this example I can see no difference between them and Singletons.
    Precisely the point. A singleton object is a global object, but it's easily replaceable by a normal object later on. It's a matter of your personal preferences whether you prefer this :
    PHP Code:
    $db =& $_GLOBALS['__db'];
    $db->someMethod(); 
    over this :
    PHP Code:
    $db =& DB::GetSingleton();
    $db->someMethod(); 
    The second one makes it easier to change the name of the variable if you encounter namespace-conflicts at some point. Besides it gives you the option to not instantiate the object until it's actually being used.

  7. #7
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by johno
    I know that globals are evil, but in this example I can see no difference between them and Singletons.
    That's why people write artcles titled Singletons are evil!

    Though, even if they are "evil", that doesn't mean you can't use them

    Quote Originally Posted by johno
    Hmm, I don't think this violates pure OO coding style much more than some if() then else, foreach() and while(){} code.
    It makes sense if you look at it from a responsibilities perspective - in OOP responsibilities are given to objects, not collections of functions. That doesn't mean to say that collections of functions couldn't take on the responsibilities, just that in OO you tend not to.

    Douglas
    Hello World

  8. #8
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The bigest single point of difference between the $db = DB::getInstance() and $db = $GLOBALS=['db'] is that you can ensure proper instanciation of the global in DB::getInstance() and in the global version you are implicitly relying on the fact that you have correctly instanciated the global variable before use.
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  9. #9
    SitePoint Zealot johno's Avatar
    Join Date
    Sep 2003
    Location
    Bratislava, Slovakia
    Posts
    184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sweatje
    The bigest single point of difference between the $db = DB::getInstance() and $db = $GLOBALS=['db'] is that you can ensure proper instanciation of the global in DB::getInstance() and in the global version you are implicitly relying on the fact that you have correctly instanciated the global variable before use.
    Yes, lazy instanciation is a good example where Singleton is better than Monostate. But i can imagine some cases where lazy instanciation is not a plus.

    Thanks, for the comments guys. I still see some place for Monostate in PHP, but now I know where the usage of Singletons will be better.
    Annotations support for PHP5
    TC/OPT™ Group Leader

  10. #10
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sweatje
    $db = $GLOBALS=['db']
    Is that monostate/singleton or just "an object reference stored in a GLOBAL"?

    Douglas
    Hello World

  11. #11
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    Is that monostate/singleton or just "an object reference stored in a GLOBAL"?

    Douglas
    Monostate information should be held statically (implementations may vary, but should all be done through initialization of each instance) so it would apply only to the Singleton vs. Global argument.

  12. #12
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is that monostate/singleton or just "an object reference stored in a GLOBAL"?
    I'd say Singleton is OO-jargon for "global object".

  13. #13
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    I'd say Singleton is OO-jargon for "global object".
    Global, Singleton, MonoState (the above wasn't strictly a MonoState, but near enough) and Registry all provide global access. A situation where I am forced to use globally accessable information is not one I want to be in, but if I am I'll choose the Registry first and the Singleton second.

    The registry allows testing, because I can fiddle with the entries externally to the code being tested. Still awkward though.

    The Singleton makes the global behaviour much more visible in the client code. The Monostate hides the global nature. This makes it easier to understand the code and to refactor in a very explicit way. the Monostate breaks the rule of least surprise.

    The real issue of course is whether you really need this data global at all. OO provides a wealth of alternate patterns. We are certainly not short of ways to refactor our code to allow passing of the data around or localising it to the code where it is needed. Any kind of global data will cause issues, not least in testing.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  14. #14
    SitePoint Zealot johno's Avatar
    Join Date
    Sep 2003
    Location
    Bratislava, Slovakia
    Posts
    184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think I've found something interesting.
    http://www.objectmentor.com/resource...dMonostate.pdf
    Annotations support for PHP5
    TC/OPT™ Group Leader

  15. #15
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by feti
    Oh, I'd point my finger to efficiency. In order to appreciate how things work when they're done properly and to understand them, understanding the very basics of computers is a necessity. I'd suggest picking up a C book or ASM if you've got a bit of time. And while you're at it, go pick up the Pragmatic Programmer.

    I know this isn't the answer you wanted. And I probably sound like a jerk. But there comes a time when people that call themselves programmers stop being lazy and be so quick to question why, why, why, when they should take that time to understand and read.
    There are no stupid questions, only stupid people.
    Why on earth would you discourage questions or discussions.
    You're input was completely useless and not only didnt answer his question, but for no logical coherent reason tried to cut his learning by making him feel like he shouldnt ask questions.
    If you have nothing productive to say, don't say anything.

    As far as reasons for using singleton go - I prefer singlton because you don't have any extra code. If i need a db instance, I'll just use it:

    PHP Code:
    ConfigParams::GetValue("param_name"
    so I don't have to write global $config_params at the start of every function. I find it cleaner code.
    Other than there is little difference. They are both held globally.

  16. #16
    SitePoint Zealot johno's Avatar
    Join Date
    Sep 2003
    Location
    Bratislava, Slovakia
    Posts
    184
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lazy_yogi
    As far as reasons for using singleton go - I prefer singlton because you don't have any extra code. If i need a db instance, I'll just use it:

    PHP Code:
    ConfigParams::GetValue("param_name"
    so I don't have to write global $config_params at the start of every function. I find it cleaner code.
    Other than there is little difference. They are both held globally.
    I'm not sure but I think you are not talking about singleton. In fact I think you are using some sort of Monostate, because with singleton you have to write
    PHP Code:
    $something ConfigParams::getInstance(); 
    "instead of"
    PHP Code:
    global $something
    In every function/method where you need to use it.
    Annotations support for PHP5
    TC/OPT™ Group Leader

  17. #17
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, I haven't read about monostate, but with that link posted it seems I'm using that.
    There are very subtle differences, and in most cases there would be no difference in its use. In singleton the class has a static instance of the class itself - and there is just one instance of each member in the class because of this, and in monostate, the class just has static instances of the members which you access individually.
    This seems to me that any difference would be in the behaviour of the class methods that provide behaviour on the data items, but I'm too tired to think about that right now, so I'm heading off to the land of nod =)

  18. #18
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I find myself using monostate when there are several methods that logically relate to each other, but don't share any class properties, and a singleton when I have an object that stores properties, but only ever want one instance of it floating around. They both achieve that global access, but are subtley different in how it happens. The important thing about them as opposed to using global $variables; all over the place is that you can control how those variables are accessed and manipulated.

  19. #19
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I find myself using monostate when there are several methods that logically relate to each other, but don't share any class properties
    Witch is why I sometimes miss namespaces under php. PEAR does this by using underscores to sepearate packages. It may look ugly, but I kind of prefer this solution, since it allows for hierachies instead of just one level of namespace.
    Eg. You can't do Http::Socket::Util but you could do Http_Socket_Util
    Last edited by kyberfabrikken; Dec 9, 2004 at 07:44. Reason: brain meltdown

  20. #20
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Like tanus I use the Monostate for things like File system functions

    class FileSystemUtils {
    static CopyRecursive($src, $dest);
    static DeleteRecursive($target);
    static MkdirRecursive($folder);
    }

    Singletons are better when you deal with data though. If you ever need to go from using global data to using a identity map, a singleton is easier to migrate over than a monostate.

  21. #21
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tanus
    I find myself using monostate when there are several methods that logically relate to each other, but don't share any class properties, and a singleton when I have an object that stores properties, but only ever want one instance of it floating around. They both achieve that global access, but are subtley different in how it happens. The important thing about them as opposed to using global $variables; all over the place is that you can control how those variables are accessed and manipulated.
    For use or properties, you can use either and they work the same way. I can't see any difference in using these two below. In both situations, the properties you access will always be from one instance. Do you have an example where one would make a difference over the other? If it is where you have a group of methods without properties, why not just make a regular class and instantiate it?

    Regards,
    Eli

    PHP Code:
    class Singleton
    {
        private 
    string var1 "var1";;
        private 
    string var2 "var2";
     
        private 
    Singleton singleton
        
    public static Singleton GetInstance()
        {
            return 
    singleton;
        }
     
        public 
    string GetVar1()
        {
            return 
    var1;
        }
     
        public 
    string GetVar2()
        {
            return 
    var2;
        }
    }
     
    Singleton s Singleton.GetInstance();
    print 
    s.GetVar1(); 
    PHP Code:
    class MonoState
    {
        private static 
    string var1 "var1";;
        private static 
    string var2 "var2";
     
        public static 
    string GetVar1()
        {
            return 
    var1;
        }
     
        public static 
    string GetVar2()
        {
            return 
    var2;
        }
    }
     
    print 
    MonoState.GetVar1(); 

  22. #22
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lazy_yogi
    For use or properties, you can use either and they work the same way. I can't see any difference in using these two below.
    It would help if you had posted PHP examples, these are subtle differences so posting examples in different languages isn't going to make anything clearer imo.

    From the perspective of the calling code:

    PHP Code:
    $string_utils string_utils::getInstance();
    $string_utils->do_something_fancy('A string');

    // vs

    string_utils::do_something_fancy('A string'); 
    If it really is a function lib, using a monostate class is a bit like a namespace. Using either syntax, it is impossible to say whether the class is storing internal state or not, but the bottom one looks like it isn't, so in a case where you don't, it might make it more descriptive.

    For myself, I just make a PHP file, chuck in some functions, and code like this:

    PHP Code:
    include_once 'my_string_functions.php';
    my_string_utils_do_something_fancy('A string'); 
    Perhaps not so long a prefix though

    It is how PHP does it: just scan the list at http://www.php.net/quickref.php and you'll see prefixes all over the place.

    Douglas
    Hello World

  23. #23
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lazy_yogi
    For use or properties, you can use either and they work the same way. I can't see any difference in using these two below. In both situations, the properties you access will always be from one instance. Do you have an example where one would make a difference over the other? If it is where you have a group of methods without properties, why not just make a regular class and instantiate it?

    Regards,
    Eli

    PHP Code:
    class Singleton
    {
        private 
    string var1 "var1";;
        private 
    string var2 "var2";
     
        private 
    Singleton singleton
        
    public static Singleton GetInstance()
        {
            return 
    singleton;
        }
     
        public 
    string GetVar1()
        {
            return 
    var1;
        }
     
        public 
    string GetVar2()
        {
            return 
    var2;
        }
    }
     
    Singleton s Singleton.GetInstance();
    print 
    s.GetVar1(); 
    PHP Code:
    class MonoState
    {
        private static 
    string var1 "var1";;
        private static 
    string var2 "var2";
     
        public static 
    string GetVar1()
        {
            return 
    var1;
        }
     
        public static 
    string GetVar2()
        {
            return 
    var2;
        }
    }
     
    print 
    MonoState.GetVar1(); 
    The main reason is that the properties of the MonoState class are static; if you were to create a couple of instances of the MonoState each instance would be sharing the same properties. This has the same effect as the singleton, but in some cases you might want your MonoState to have its own instance specific properties also. But in most practical applications you're correct, the end result is the same.

  24. #24
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In that case the difference lies more in it's use. If you create a 'monostate' class with all class data being static, it's basically the same as a singleton (which has been how i've used it).
    But if you create it with some other non-static class data also, it's basically a regular class with some static variables - which i suppose is the point of giving it a seperate name ('monostate').

    And in that case, the static variables in a monostate's object are global to their own objects only, so there is still some data/information-hiding which is a plus.

    Thanks for the explaination,
    Eli

  25. #25
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, monostate when used in instantiated objects provides global data access only to other classes of the same type (until you add accessors etc). The PDF someone linked up above gives a pretty good explanation of it.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •