Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.
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?
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 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?
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:
so you just iterate thru the list and just update everything. i love it. that is just one use but just an example
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
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.
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
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...
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.
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.
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.
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.