Page 1 of 3

I don't know if this is Singleton but...

Posted: Thu Feb 26, 2009 5:57 am
by = odino =
Ciao guys,

I'm new of the forum but I would like to ask you a few questions: if this is not the right section... blame me! :roll:

I've got two blocks of OOP code, that can do the same tasks, in just a (bit) different way.

Singleton pattern

Code: Select all

 
class MYSQL {
    
    static private $instance = NULL;
    
    static function getInstance() 
    {
        if (!self::$instance instanceof self) 
        { 
            self::$instance = new self;
        }
        return self::$instance;
    }
    
    function conn ($_HOST, $DB_USER, $DB_PASS)
    {
        mysql_connect($_HOST, $_DB_USER, $_DB_PASSWD) or die("You dummy coder!");
    }
 
    private function __construct ()
    {
        ...
    }
 
    private function __clone ()
    {
        ...
    }
}
 
which can execute from anywhere into the script the connect method, calling:

MYSQL::getInstance()->connect(...);

The I Don't Know pattern

Code: Select all

 
class MYSQL {
    
    function conn ($_HOST, $DB_USER, $DB_PASS)
    {
        mysql_connect($_HOST, $_DB_USER, $_DB_PASSWD) or die("You dummy coder!");
    }
 
    private function __construct ()
    {
        ...
    }
 
    private function __clone ()
    {
        ...
    }
}
 
which can execute from anywhere into the script the connect method, calling:

MYSQL::connect(...);

Any idea about the difference between these 2 patterns?

I think that probably script's security is involved...but...i truly don't know...

Re: I don't know if this is Singleton but...

Posted: Sat Feb 28, 2009 10:21 pm
by josh
The second one is not a pattern, its just calling the method statically

Re: I don't know if this is Singleton but...

Posted: Sun Mar 01, 2009 1:20 pm
by = odino =
Ciao Josh,

yes man, you're right.

But, wait just a second, they do the same stuff, don't they?

I'm wondering if the use of Singleton, in similar cases, is a waste of time...

:)

Re: I don't know if this is Singleton but...

Posted: Sun Mar 01, 2009 9:47 pm
by Christopher
They are the same because the mysql library is itself a Singleton of sorts in that it holds the current connection and uses it as a default for all functions.

Re: I don't know if this is Singleton but...

Posted: Sun Mar 01, 2009 11:11 pm
by josh
Singleton uses a static method to get ahold of an instance of the class. When you call a static method no objects are involved, its like using old school functions. Singleton is basically just a class with a function that is called statically to get an instance of an object to operate on in the OO way.

Re: I don't know if this is Singleton but...

Posted: Sun Mar 01, 2009 11:20 pm
by Chris Corbyn
josh wrote:Singleton uses a static method to get ahold of an instance of the class. When you call a static method no objects are involved, its like using old school functions. Singleton is basically just a class with a function that is called statically to get an instance of an object to operate on in the OO way.
That could be a bit misleading. Although using a static factory method is the commonly used approach for singletons it's not actually part of the pattern itself.

The second implementation posted here, can't even be instantiated so what ~arborint is saying (I assume) is that since the only functionality it seems to offer is to perform mysql_connect() calls which by sheer coincidence yields a single connection then it's more or less wrapping singleton logic. It's not really a singleton itself though... it's more like a glorified mysql_connect() wrapper.

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 1:17 am
by Christopher
Chris Corbyn wrote:That could be a bit misleading. Although using a static factory method is the commonly used approach for singletons it's not actually part of the pattern itself.
Yeah. Check out how Ruby or Python or C# do Singletons. No static+genInstance() stuff like Java. Imagine in PHP if we could do this and new would only ever return one instance:

Code: Select all

singleton class Foo {
}
Chris Corbyn wrote:The second implementation posted here, can't even be instantiated so what ~arborint is saying (I assume) is that since the only functionality it seems to offer is to perform mysql_connect() calls which by sheer coincidence yields a single connection then it's more or less wrapping singleton logic. It's not really a singleton itself though... it's more like a glorified mysql_connect() wrapper.
It's funny, but if the guy did $db = new MYSQL() it would still work. That's because the global var in the mysql library makes it easy. And let's admit it -- globals make it easy, but open you up to side-effects. When people wrap a global in a static class call, what they are really doing is protecting themselves from the side-effect of the global being overwritten. But if the global is an object there is still the potential for side-effect problems. I honestly can't think of a time in these forums when someone actually was having the problem that Singleton solves. They always really want a global or Monostate.

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 4:05 am
by josh
it could also be implemented using globals, same end effect though

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 4:29 am
by Chris Corbyn
arborint wrote:It's funny, but if the guy did $db = new MYSQL() it would still work. That's because the global var in the mysql library makes it easy.
You'd be completely right if it wasn't for this :P

Code: Select all

private function __construct ()
Just being a pedant ;)
And let's admit it -- globals make it easy, but open you up to side-effects. When people wrap a global in a static class call, what they are really doing is protecting themselves from the side-effect of the global being overwritten. But if the global is an object there is still the potential for side-effect problems. I honestly can't think of a time in these forums when someone actually was having the problem that Singleton solves. They always really want a global or Monostate.
Too true! I'm sure you still use singletons at times (do you?)... I know I do. I always question my reasoning when I do though ;) I'm also a lazy programmer... duh duh daahhhh!

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 5:19 am
by josh
I used a "keyed" singleton for my data mapper library, that is, each concrete mapper subclass can only have 1 instance, uses a static array of instances instead of 1 single instance. The name of the class is an index in the array

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 8:14 am
by = odino =
Thanks for your replies men...

So, in you opinion, implementing the second "pattern" I've posted it's completely silly, or not?

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 11:57 am
by josh
Its not the feature itself thats silly, it depends on if you abuse it

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 1:38 pm
by = odino =
:wink:

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 2:32 pm
by VladSun
josh wrote:I used a "keyed" singleton for my data mapper library, that is, each concrete mapper subclass can only have 1 instance, uses a static array of instances instead of 1 single instance. The name of the class is an index in the array
In C# I used a "object-parameter-keyed" singleton for providing Font objects - I needed bold, bold+italic, etc. font styles for a huge Treenode interface :)

Re: I don't know if this is Singleton but...

Posted: Mon Mar 02, 2009 2:41 pm
by mickeyunderscore
I have a singleton database wrapper that I use to access the database. It has the mysql_connect() function in the __construct() method, rather than as a separate method which must be called.

I used the singleton pattern because I wanted to make sure I wasn't creating loads of instances of essentially the same thing.

If find it useful as I have a debug() method which I can send different parameters to, telling the class to collect or echo all database queries sent to it for example.

I wrote this when I was very new to PHP so there may be a better way.