Page 1 of 2

Static Class Versus Singleton

Posted: Mon Sep 18, 2006 9:39 am
by Ollie Saunders
Head First Design Patterns wrote:Q: Can't I just create a class in which all methods and variables are defined as static? Wouldn't that be the same as a singleton?

A: Yes, if your class is self-contained and doesn't depend on complex initialization. However, because of the way static initializations are handled in Java, this can get very messy, especially if multiple classes are involved. Often this scenario can result in subtle, hard to find bugs involving order of initialization. Unless there is a compelling need to implement your "singleton" this way, it is far better to stay in the object world.
In particular Head First Design Patterns wrote:Unless there is a compelling need to implement your "singleton" this way, it is far better to stay in the object world.
To which I ask: Why?
And what should I consider a complex initialization?

Is this, for instance, a complex initialization:

Code: Select all

static public function init($enc, $supressNotice = false)
{
    static $called = false;
    if ($called) {
        $errStr = 'Attempted to initialize ' . __CLASS__ . ' for a second time';
        throw new OF_Exception($errStr, OF_Exception::MISC);
    }
    if (get_magic_quotes_gpc() and !$supressNotice) {
        $errStr = 'You have magic_quotes_gpc enabled on this server, this ca'
                . 'n cause erroneous slashes (/) to appear in your database/'
                . 'output.<br / ><br />You can supress the effects of magic_'
                . 'quotes_gpc with OF::antiMagicQuote(). A better idea howev'
                . 'er is to turn off magic_quotes completely. This can be do'
                . 'ne in php.ini (<code>magic_quotes_gpc = Off</code>) or .h'
                . 'taccess with (<code>php_flag magic_quotes_gpc off</code>).';
        trigger_error($errStr, E_USER_NOTICE);
    }
    self::$enc = new OF_Enc($enc);
    self::$registry = new OF_Registry();
    self::$_idRegistry = new OF_Registry(null);
    $called = true;
}
I can't think of any problems with this.

Posted: Mon Sep 18, 2006 10:14 am
by Christopher
I guess I wonder why you would not just put that code in the constructor where it is my definintion only called once? And why not use normal properties? What is the purpose of a separate init() method?

Posted: Mon Sep 18, 2006 11:15 am
by MrPotatoes
singletons are GREAT in C++. i love em'. it makes so much stuff easier

you can do a linked list (or use the STL vector class) and create the type as the base class type you can push/pop all the child parts in there. if they all have an update that's even better because you can update everything by doing this:

Code: Select all

$VectorObject[i]->update(time());
so you just iterate thru the list and just update everything. i love it. that is just one use but just an example :D

i have to say tho, something in PHP and singletons don't mix with me. it just seems like it'll be ripe for hacking because it just doesn't seem as secure to me for some reason. i dunno why tho. i haven't looked into it enough so don't ask me lmo

Posted: Mon Sep 18, 2006 11:18 am
by Luke
MrPotatoes wrote:i have to say tho, something in PHP and singletons don't mix with me.
I'm not a real big fan of php singletons either... I just don't feel very comfortable using them...

Posted: Mon Sep 18, 2006 11:30 am
by Ollie Saunders
arborint wrote:I guess I wonder why you would not just put that code in the constructor where it is my definintion only called once? And why not use normal properties? What is the purpose of a separate init() method?
Its a static class
you can do a linked list (or use the STL vector class) and create the type as the base class type you can push/pop all the child parts in there. if they all have an update that's even better because you can update everything by doing this:
Isn't that a container? If so, I don't think singletons have a great deal to do with why you think that is great.

Posted: Mon Sep 18, 2006 12:12 pm
by Christopher
ole wrote:Its a static class
Why?
MrPotatoes wrote:singletons are GREAT in C++. i love em'. it makes so much stuff easier
Yeah ... Singleton as memory manager is a cool trick using STL, but let's not forget that it is not really the pattern as intended there.

Posted: Mon Sep 18, 2006 12:17 pm
by MrPotatoes
it's a container of singletons. singletons are great because you can only have one of those in memory at any given time otherwise it should throw an error. it works great in Cpp but i'm not sure how to do it in PHP cuz yo don't handle your own memory

it's like this in memory:
[s(x)]->[s(x)]->[s(x)]->[s(x)]->[s(x)]->[s(x)]->

each container "[]" has a singleton class in it. i don't know how to explain it because you only have on singleton (of the base class) but you store the child classes within eash suceeding container. when i go home i'll get the code and paste some pusedo code in there. it's really sweet and makes alot of things easier i'll tell you what

now that i think of it my loader class could be a singleton (PHP). i should go ahead and do that

Posted: Mon Sep 18, 2006 12:29 pm
by Ollie Saunders
arborint wrote:
ole wrote:Its a static class
Why?
Because I only want one copy that I can access globally.

Posted: Mon Sep 18, 2006 12:44 pm
by Christopher
ole wrote:Because I only want one copy
Then only create one copy.
ole wrote: that I can access globally.
I would recommend looking into the many alternatives to using globals.

Posted: Mon Sep 18, 2006 1:32 pm
by Chris Corbyn
The only time I use static classes are for static registries and for configuration directives. The static registry is where I would place anything I waned to access the same instance of globally.

If your class is completely static it's very difficult to reset it's state (i.e. s ingleton could contain a method like such...

Code: Select all

static public function destroy()
    {
        self::$instance = null;
    }
To achieve anything similar with a static class you'd need to go through the whole thing and reset each value one-by-one. A static class is more like a collection of globals in a smaller namespace than an instance of an object with a known state. Monostate? Hmm... almost a little too-so.

Posted: Mon Sep 18, 2006 5:57 pm
by Ollie Saunders
Ahh yes, d11wtq, you have a good reason there.
This is where I have to ask myself how often do I need to reset the state of my static classes? Not very often, I think.

But yes that is an interesting thing to know and exactly the kind of response I was looking for from my initial post.

I think I am clear in my mind when I should use a singleton and when I should use a static class and the reasons why. So then that begs another question:
Since I'm writing a library shouldn't I try to instil some consistency in order to make it easier to learn and choose one or the other in accordance with that. If that is the case I would have to go for a singleton so that I could make use of stateful single instance classes when need arises.

Posted: Tue Sep 19, 2006 12:23 am
by Chris Corbyn
Is there a reason you can't use a registry? You could always wrapper the fact that it's using a registry by creating a factory function/method which registers it at first manufacture.

Posted: Tue Sep 19, 2006 4:53 am
by Ollie Saunders
Statics and objects need a different access method, which is where the inconsistency lies and isn't something a registry could solve.

Posted: Tue Sep 19, 2006 5:09 am
by Jenk
a Registry normally goes hand in hand with a Singleton, thus it has a static method for retrieving the registry instance; ergo it has global access.

Code: Select all

$reg = Registry::getInstance();

$myObj = $reg->retrieve('myObj');

$myObj->myMethod();

Posted: Tue Sep 19, 2006 1:03 pm
by Christopher
Although by injecting the Registry using a controller architecture you don't even need the overhead of the Singleton because there just isn't the circumstance to create duplicates.