|
|
 | | From: | Calum Grant | | Subject: | Singletons | | Date: | Sat, 15 Jan 2005 15:17:35 GMT |
|
|
 | I quite often see singletons in code, and I think they are overused.
Singletons have the disadvantage that everyone in the whole world has access to that object, which is as bad as a global function. Anyone can call a singleton and create havoc on it.
Singletons also introduce hard-coded dependencies that are difficult to break if one wishes to change the environment or reuse some of the classes in a different project.
Just because you call something a "singleton" instead of a global variable does not make it a good pattern.
Singletons are lazy design, since "global scope" is too broad a scope for most objects.
So my point is this: singletons should be discouraged, even banned.
Calum
|
|
 | | From: | H. S. Lahman | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 21:29:46 GMT |
|
|
 | Responding to Grant...
> I quite often see singletons in code, and I think they are overused.
That is very true. They should only be used when two conditions both prevail:
(1) The must never be more than one instance of the object.
(2) There are multiple opportunities to create an instance during execution because
(2a) An instance can be created in different contexts (i.e., by different objects) and/or
(2b) The instantiating behavior can be invoked multiple times.
However, when those conditions prevail Singleton is usually the best (safest and most readily understood) mechanism.
> > Singletons have the disadvantage that everyone in the whole world has > access to that object, which is as bad as a global function. Anyone can > call a singleton and create havoc on it.
All public object attributes are global in this sense. They can be accessed by any object in the application having a valid relationship navigation path to traverse to reach the target object. But...
> > Singletons also introduce hard-coded dependencies that are difficult to > break if one wishes to change the environment or reuse some of the > classes in a different project. > > Just because you call something a "singleton" instead of a global > variable does not make it a good pattern. > > Singletons are lazy design, since "global scope" is too broad a scope > for most objects.
This ignores that the primary technique for managing persistent state in OO development is relationship instantiation. One can only reach objects to access their state variables if a relationship path exists to reach them.
1 paid by R1 * [Department] ------------------- [Professor] | 1 | 1 | majors in | taught by | | | R2 | R3 | | | * R4 | * [Student] ---------------------- [Course] * | attends * | [Registration]
Now when a Professor seeks to grade a Student, the Professor is limited to those Students that can be accessed by the R3 -> R4 relationship navigation, which will be a smallish subset of all Students. It is up to the developer to ensure that the dynamics navigate the correct relationship path during collaborations. Thus grading all Students reached by R1 -> R2 would be invalid because the resulting set of Students via that path is a superset of the Students resulting from the R3 -> R4 path that restricts grading to Course that the Professor teaches.
************* There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions -- Put MDA to Work http://www.pathfindermda.com blog (under constr): http://pathfinderpeople.blogs.com/hslahman (888)-OOA-PATH
|
|
 | | From: | Jimmy Cerra | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 01:08:33 GMT |
|
|
 | H. S. Lahman wrote: > That is very true. They should only be used when two conditions both > prevail: > > (1) The must never be more than one instance of the object. > > (2) There are multiple opportunities to create an instance during > execution because > > (2a) An instance can be created in different contexts (i.e., by > different objects) and/or > > (2b) The instantiating behavior can be invoked multiple times. > > However, when those conditions prevail Singleton is usually the best > (safest and most readily understood) mechanism.
Do objects that manage the creation of other objects usually make good Singletons? Like Abstract Factories implementations, Object Pools/Managers, and the like?
In fact, I think this lets the singleton be more flexible and less risky. That is, if you think a class should be a singleton, make the constructor protected and allow it to be managed by a seperate singleton object manager. If you change your mind, you only have to change the manager's code, or even just write another manager. E.G.
Say you origionally think Window objects hould be singletons. So write this instead of the classic pattern. (note: there are better Singleton implementations... I chose this one for brevity):
] package Motif; ] public class Window { ] protected Window() {...} ] }
] package Motif; ] import Motif.Window; ] public class WindowManager { ] private static WindowManager wm = new WindowManager(); ] private static Window ww = new Window(); ] protected WindowManager() {...} ] public static getInstance() {return wm;} ] public getWindow() {return ww;} ] }
If you change your mind, then either change WindowManager or (better) create a new manager:
] package Motif; ] import Motif.Window; ] public class WindowManager2 { ] private static WindowManager2 wm = new WindowManager2(); ] protected WindowManager2() {...} ] public static getInstance() {return wm;} ] public getWindow() {return new Window();} ] }
It also allows Window objects to be easily extended (singletons are traditionally hard to extend or subclass).
-- Jimmy Cerra https://nemo.dev.java.net/
|
|
 | | From: | H. S. Lahman | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 04:25:55 GMT |
|
|
 | Responding to Cerra...
>> That is very true. They should only be used when two conditions both >> prevail: >> >> (1) The must never be more than one instance of the object. >> >> (2) There are multiple opportunities to create an instance during >> execution because >> >> (2a) An instance can be created in different contexts (i.e., by >> different objects) and/or >> >> (2b) The instantiating behavior can be invoked multiple times. >> >> However, when those conditions prevail Singleton is usually the best >> (safest and most readily understood) mechanism. > > > Do objects that manage the creation of other objects usually make good > Singletons? Like Abstract Factories implementations, Object > Pools/Managers, and the like?
Usually not. That's because concrete factories are usually instantiated once during application initialization. There is usually no need for more than one and it will be more efficient to allocate it once at startup than to allocate/deallocate it on an as-needed basis.
OTOH, I can envision situations where it might be desirable to create factories on an as-needed basis and get rid of them afterwards. In that case one might have a need for making them Singletons for efficiency sake because the as-needed invocation may be unpredictable or repeated.
> > In fact, I think this lets the singleton be more flexible and less > risky. That is, if you think a class should be a singleton, make the > constructor protected and allow it to be managed by a seperate singleton > object manager. If you change your mind, you only have to change the > manager's code, or even just write another manager. E.G.
Hmmm. OK, I think I may have answered a different question above than you asked. B-)
If you just mean that if one is already using a factory to create instances, then let the factory control the number rather than a static method in the class being instantiated, then I agree. That is necessarily more flexible because the factory has more control over the instance being created (i.e., in Singleton there is only one possible flavor of instance to create initially)
However, I would counter by wondering how much need there is for that flexibility. The only situation I can think of where that would be useful is when one needs one sort of single instance (read: attribute initialization) for awhile during some context but when that context is replaced one needs a different sort of single instance for awhile. IOW, one wants to be able to delete the current flavor and recreate a new flavor.
But one can do that if one adds a static delete method to Singleton. The odds are somebody else needs to understand when the context switch and whoever that is can invoke the delete() method of the singleton. Taking that one step further, whoever that is also likely to understand what new flavor of single instance is needed for the new context. So they would be a single point of instantiation and one wouldn't need a Singleton at all. B-)
> > Say you origionally think Window objects hould be singletons. So write > this instead of the classic pattern. (note: there are better Singleton > implementations... I chose this one for brevity): > > ] package Motif; > ] public class Window { > ] protected Window() {...} > ] } > > ] package Motif; > ] import Motif.Window; > ] public class WindowManager { > ] private static WindowManager wm = new WindowManager(); > ] private static Window ww = new Window(); > ] protected WindowManager() {...} > ] public static getInstance() {return wm;} > ] public getWindow() {return ww;} > ] }
OK. But unless I'm missing something this is just a Singleton (WindowManager) combined with a composition relationship
1 [WindowManager] <*>--------------- [Window]
The Whole/Part composition with unconditional 1:1 multiplicity already ensures there can't be more than one Window created for each WindowManager, so if WindowManager is a Singleton there is only one point of instantiation and Window does not need to be a Singleton.
> > If you change your mind, then either change WindowManager or (better) > create a new manager: > > ] package Motif; > ] import Motif.Window; > ] public class WindowManager2 { > ] private static WindowManager2 wm = new WindowManager2(); > ] protected WindowManager2() {...} > ] public static getInstance() {return wm;} > ] public getWindow() {return new Window();} > ] } >
OK, but WindowManager2 is a different class than WindowManager. I'm not sure I see how this is different than having any two different classes that are singletons.
> It also allows Window objects to be easily extended (singletons are > traditionally hard to extend or subclass).
I don't think subclassing should be a problem; only a leaf subclass is instantiated, so any one or all of the leaf subclasses can be a Singleton. That is, subclassing, inheritance, and polymorphism are all orthogonal to the number of instances of the leaf subclasses.
************* There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions -- Put MDA to Work http://www.pathfindermda.com blog (under constr): http://pathfinderpeople.blogs.com/hslahman (888)-OOA-PATH
|
|
 | | From: | Jimmy Cerra | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 05:34:14 GMT |
|
|
 | H. S. Lahman wrote: >> Do objects that manage the creation of other objects usually make >> good Singletons? Like Abstract Factories implementations, >> Object Pools/Managers, and the like? > > Usually not.
Why? GoF explictly states that factories make good Singletons. Mark Grand in "Patterns in Java Volume 1" says the same for Object Pools. Are they incorrect? I'm not as knowledgable as them (or you) so I don't know for certain, but that's what I read.
>> In fact, I think this lets the singleton be more flexible and less >> risky. That is, if you think a class should be a singleton, make the >> constructor protected and allow it to be managed by a seperate >> singleton object manager. If you change your mind, you only have to >> change the manager's code, or even just write another manager. E.G. > > If you just mean that if one is already using a factory to create > instances, then let the factory control the number rather than a > static method in the class being instantiated, then I agree. That is > necessarily more flexible because the factory has more control over > the instance being created (i.e., in Singleton there is only one > possible flavor of instance to create initially)
That's basically it.
> However, I would counter by wondering how much need there is for that > flexibility. The only situation I can think of where that would be > useful is when one needs one sort of single instance (read: attribute > initialization) for awhile during some context but when that context > is replaced one needs a different sort of single instance for awhile. > IOW, one wants to be able to delete the current flavor and recreate a > new flavor.
I was thinking of the situations when once an object should have been a singleton. Then later on the singleton behavior needed to be factored out, because the origional programmers were mistaken during the previous design. However, it is hard to "unsingleton" classes when some code still depends on the singleton behavior.
Therefore, I'm thinking that the singleton behavior should be placed into an external object like a factory. Then to remove the singleton behavior, one just needs to write a new factory. Both applications the old and new code can reuse the same source without modification. I think this is preferable to changing existing code.
> But one can do that if one adds a static delete method to Singleton. > The odds are somebody else needs to understand when the context switch > and whoever that is can invoke the delete() method of the singleton. > Taking that one step further, whoever that is also likely to > understand what new flavor of single instance is needed for the new > context. So they would be a single point of instantiation and one > wouldn't need a Singleton at all. B-)
Can you reexplain that?
> OK. But unless I'm missing something this is just a Singleton > (WindowManager) combined with a composition relationship > > 1 > [WindowManager] <*>--------------- [Window]
The idea is that we are certain that WindowManager can be a singleton (factories often make good singletons, according to GoF), while we are less certain that only one Window will only ever need to be created.
> OK, but WindowManager2 is a different class than WindowManager. I'm > not sure I see how this is different than having any two different > classes that are singletons.
Say Window was a singleton:
] package Motif; ] public class Window { ] private static Window ww = new Window(); ] public static getInstance() {return ww;} ] private Window() {...} ] }
Then several framework revisions later, we find this to be an error. Old code still depends on the singleton behavior, while new code would be better served with many Windows. It is messy to keep the singleton behavior and allow the constructor to be private. Factoring it out later breaks compatibility with old programs.
A more flexible design factors out the singleton behavior while initially designing Window. Then you can change the behavior by adding code rather than changing existing classes.
That's the intent of the idiom. I was just thinking outloud, anyway.
> I don't think subclassing should be a problem; only a leaf subclass is > instantiated, so any one or all of the leaf subclasses can be a > Singleton. That is, subclassing, inheritance, and polymorphism are > all orthogonal to the number of instances of the leaf subclasses.
Considerable discussion is devoted to subclassing Singletons in GoF. Mark Grand in "Patterns in Java Vol. 1" states that extending singletons is awkward.
-- Jimmy Cerra
|
|
 | | From: | H. S. Lahman | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 20:30:13 GMT |
|
|
 | Responding to Cerra...
> H. S. Lahman wrote: > >> Do objects that manage the creation of other objects usually make > >> good Singletons? Like Abstract Factories implementations, > >> Object Pools/Managers, and the like? > > > > Usually not. > > Why? GoF explictly states that factories make good Singletons. Mark > Grand in "Patterns in Java Volume 1" says the same for Object Pools. Are > they incorrect? I'm not as knowledgable as them (or you) so I don't > know for certain, but that's what I read.
Making a good Singleton _when necessary_ and determining whether they need to be Singletons are two quite different things. There usually aren't multiple opportunities for instantiating a concrete factory, so there is no need for the complexity. OTOH, when there are multiple instantiation opportunities, then factories are good candidates for Singleton.
> I was thinking of the situations when once an object should have been a > singleton. Then later on the singleton behavior needed to be factored > out, because the origional programmers were mistaken during the previous > design. However, it is hard to "unsingleton" classes when some code > still depends on the singleton behavior. > > Therefore, I'm thinking that the singleton behavior should be placed > into an external object like a factory. Then to remove the singleton > behavior, one just needs to write a new factory. Both applications the > old and new code can reuse the same source without modification. I > think this is preferable to changing existing code.
But who is accessing the instance() behavior? That will only be those who are creating it or instantiating relationships with it when instantiating other objects (i.e., factories). If there is a change in the requirements (or the original design was in error), they are going to have to be modified anyway.
Just in case, let me belabor the difference between instantiation and navigation of relationships. The instance() method should never be invoked simply to navigate a relationship during collaboration. When an instance is created, all of the necessary relationships with that instance should be instantiated as well. For example, reference attributes that implement the relationships will be assigned the address returned by the instance() function when the relationships are instantiated.
Then any collaborations with the instance by other objects during the solution execution should be done by navigating the existing relationships to get to it. So we have:
* 1 1 * [X] ------------- [Y] ---------------- [Z]
If Y must be a Singleton that is completely independent of the relationships with [X] and [Z] that are navigated during collaboration. If Y happens to be a single instance, then every [X] and [Z] instance will just happen to have a relationship to exactly the same instance of [Y]. When an X or Z needs to collaborate with its Y it will navigate the relationship that was instantiated with it or the [Y] instance was instantiated. This is no different than any other relationship navigation between collaborating objects; the Singleton just ensures all relationships end up with one instance reference when they are instantiated.
[Note that when a [X] or [Y] instance is created after a Y exists, the relationship must be instantiated. In that case it may be convenient for the factory creating the X or Z to invoke the instance() method. But that is not necessary because the factory itself may have a relationship with the Y that is instantiated by the [Y] factory.]
> > > But one can do that if one adds a static delete method to Singleton. > > The odds are somebody else needs to understand when the context switch > > and whoever that is can invoke the delete() method of the singleton. > > Taking that one step further, whoever that is also likely to > > understand what new flavor of single instance is needed for the new > > context. So they would be a single point of instantiation and one > > wouldn't need a Singleton at all. B-) > > Can you reexplain that?
Context A: All collaborations with [Y] above need a single Y instance that is initialized with particular set of attribute values.
Context B: All collaborations with [Y] above need a single Y instance that is initialized with particular but different set of attribute values.
Context A and B prevail for extended periods of time during the application execution but they never coexist and they exist serially. Suppose context A prevails first and one creates a Singleton with the appropriate values. (Do that parametrically via an argument to instance(CONTEXT_A).)
Now context B replaces context A. One solution is to delete the [Y] instance and recreate it by invoking instance(CONTEXT_B). But one needs a static delete() method in the Singleton that is a no-op if there is no instance.
[Alternatively, one can provide a context state variable somewhere that the Singleton instance() method looks at to determine CONTEXT_A vs. CONTEXT_B. Then if there is no instance, it creates one with the correct initialization. If there is an instance consistent with the context, the method does nothing. If there is an instance but it is inconsistent with the current context, then the current instance is deleted and an appropriate one is created.]
> > > OK. But unless I'm missing something this is just a Singleton > > (WindowManager) combined with a composition relationship > > > > 1 > > [WindowManager] <*>--------------- [Window] > > The idea is that we are certain that WindowManager can be a singleton > (factories often make good singletons, according to GoF), while we are > less certain that only one Window will only ever need to be created.
OK, but the requirements have to be clear on this. Either you need a single instance or not. That governs the multiplicity of the relationship, which determines the how many Windows one needs. The Whole/Part of the composition relationship still ensures that, since there is only one WindowManager, the number of Windows (ww) that are embedded in its definition are the only windows around. If the multiplicity is 1, then there is no opportunity to create more Windows, so one doesn't need a Singleton for Window even if the requirements say there must be only a single instance.
> > > OK, but WindowManager2 is a different class than WindowManager. I'm > > not sure I see how this is different than having any two different > > classes that are singletons. > > Say Window was a singleton: > > ] package Motif; > ] public class Window { > ] private static Window ww = new Window(); > ] public static getInstance() {return ww;} > ] private Window() {...} > ] } > > Then several framework revisions later, we find this to be an error. Old > code still depends on the singleton behavior, while new code would be > better served with many Windows. It is messy to keep the singleton > behavior and allow the constructor to be private. Factoring it out > later breaks compatibility with old programs.
I push back with my opening point about relationship instantiation vs. navigation. The relationships must be instantiated correctly and that is always part of the responsibility for instance creation. Once the relationships are instantiated properly, the navigation during collaborations will /always/ get to the right place, regardless of whether it is a Singleton or not.
Encapsulating the rules and policies of instantiation is one of the reasons we have factories in the first place. Collaborations should not need to understand those rules an policies; they should only be concerned with the nature of the collaboration (e.g., message sent) rather than whether they are collaborating with the right instance. Nor should collaborators need to understand the implementation mechanisms of instantiation (i.e., the instance() method).
So the only objects that need to understand instance() are the objects that create the instances (e.g., WindowManager) and their relationships. Those are exactly the same objects that will have to be modified if one changes the rules and policies of instantiation (e.g., ensuring Window is has a single instance).
> > I don't think subclassing should be a problem; only a leaf subclass is > > instantiated, so any one or all of the leaf subclasses can be a > > Singleton. That is, subclassing, inheritance, and polymorphism are > > all orthogonal to the number of instances of the leaf subclasses. > > Considerable discussion is devoted to subclassing Singletons in GoF.
The problem GoF has is that it is trying support poor OOA/D techniques. (And possibly catering to poorly formed OOPLs like C++ that allow superclass instantiation without specifying a specific leaf subclass.)
When an instance is instantiated from a subclassing tree there is no polymorphic access; one must instantiate a specific leaf subclass object. If one does that, then there is no problem in inheriting the instance() method while providing a leaf implementation and having a local, properly typed _instance pointer for the leaf subclass that the local implementation of instance() accesses and having it return the relevant superclass type.
However, that's kind of pointless because the subclasses are superfluous since the clients can then only access the superclass properties.
The alternative -- which is a very bad OOA/D practice -- is for the clients to query the instance to determine what subclass it actually belongs to so that specializations can be accessed. So the bottom line is: Don't Do That. Define instance() and _instance only at the leaf subclass level where static class properties should be.
They also seem to assume that one will access instance() during collaborations -- another poor OOA/D technique, as indicated above. Instance() exists to instantiate objects, not to provide collaboration message addressing.
> Mark Grand in "Patterns in Java Vol. 1" states that extending singletons > is awkward.
Sorry, I don't do Java so I haven't seen it.
************* There is nothing wrong with me that could not be cured by a capful of Drano.
H. S. Lahman hsl@pathfindermda.com Pathfinder Solutions -- Put MDA to Work http://www.pathfindermda.com blog (under constr): http://pathfinderpeople.blogs.com/hslahman (888)-OOA-PATH
|
|
 | | From: | Daniel T. | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 15:49:03 GMT |
|
|
 | In article , Calum Grant wrote:
> I quite often see singletons in code, and I think they are overused. > > Singletons have the disadvantage that everyone in the whole world has > access to that object, which is as bad as a global function. Anyone can > call a singleton and create havoc on it. > > Singletons also introduce hard-coded dependencies that are difficult to > break if one wishes to change the environment or reuse some of the > classes in a different project. > > Just because you call something a "singleton" instead of a global > variable does not make it a good pattern. > > Singletons are lazy design, since "global scope" is too broad a scope > for most objects. > > So my point is this: singletons should be discouraged, even banned. > > Calum
What about a singleton at package scope (as opposed to global scope?)
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 16:51:39 +0100 |
|
|
 | http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
Cheers, Ilja
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Wed, 19 Jan 2005 01:51:12 GMT |
|
|
 | Ilja Preuß coughed up: > http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne > > Cheers, Ilja
eh. Whole lot of hoopla about nuthin. Singletons shouldn't be overused, but so what? They aren't the end of the world either. (unlike operator overloading, which /is/ one of the four horsemen OTA :) )
He mentions his SIS uncle bobism:
public class Singleton { private Singleton() {} private static Singleton instance = new Singleton(); public static Singleton instance() {return instance;} }
I use this form, but he pointed out to me once that the following is better (and I agree), but he doesn't use this in his article:
public class Singleton { private Singleton() {} public static final Singleton instance = new Singleton(); }
I really don't see JCO as a particular win at all.
Now this is to the side of whether or not you /should/ use singletons, or even unenforced lonely instances. That is, if you do get to the point of Just Create One, then heck, you've made the lonely decision and committed the sin, you might as well make it un-@#$%up-able by some later engineer and enforce it.
-- Forgetthesong,I'dratherhavethefrontallobotomy...
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Wed, 19 Jan 2005 19:28:27 +0100 |
|
|
 | Thomas G. Marshall wrote: > That is, if you do > get to the point of Just Create One, then heck, you've made the > lonely decision and committed the sin, you might as well make it > un-@#$%up-able by some later engineer and enforce it.
Sorry, I don't understand what you are getting at here. Are you arguing that there is no difference in coupling between using a Singletong and a Just Create One?
Curious, Ilja
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Wed, 19 Jan 2005 18:33:12 GMT |
|
|
 | Ilja Preuß coughed up: > Thomas G. Marshall wrote: >> That is, if you do >> get to the point of Just Create One, then heck, you've made the >> lonely decision and committed the sin, you might as well make it >> un-@#$%up-able by some later engineer and enforce it. > > Sorry, I don't understand what you are getting at here. Are you > arguing that there is no difference in coupling between using a > Singletong and a Just Create One? > > Curious, Ilja
Coupling, shmupling. No, I'm saying that there is little difference in building an entire design around a JCO by convention vs. building an entire design around a JCO by fiat.
Like I said before: "eh."
-- "It's easier to be terrified by an enemy you admire." -Thufir Hawat, Mentat and Master of Assassins to House Atreides
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Thu, 20 Jan 2005 13:59:40 +0100 |
|
|
 | Thomas G. Marshall wrote: > Ilja Preuß coughed up: >> Thomas G. Marshall wrote: >>> That is, if you do >>> get to the point of Just Create One, then heck, you've made the >>> lonely decision and committed the sin, you might as well make it >>> un-@#$%up-able by some later engineer and enforce it. >> >> Sorry, I don't understand what you are getting at here. Are you >> arguing that there is no difference in coupling between using a >> Singletong and a Just Create One? >> >> Curious, Ilja > > > Coupling, shmupling. No, I'm saying that there is little difference > in building an entire design around a JCO by convention vs. building > an entire design around a JCO by fiat.
Is "JCO by fiat" the Singleton pattern here? If not, you managed to confuse me even more... ;)
BTW, I think that the whole point of JCO is that it's exactly *not* the entire design that is build around it. Actually almost all of its clients don't know about the number of instances.
> Like I said before: "eh."
Yes, you keep saying. Doesn't seem to help me understand your point, though...
Cheers, Ilja
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Thu, 20 Jan 2005 17:05:59 GMT |
|
|
 | Ilja Preuß coughed up: > Thomas G. Marshall wrote: >> Ilja Preuß coughed up: >>> Thomas G. Marshall wrote: >>>> That is, if you do >>>> get to the point of Just Create One, then heck, you've made the >>>> lonely decision and committed the sin, you might as well make it >>>> un-@#$%up-able by some later engineer and enforce it. >>> >>> Sorry, I don't understand what you are getting at here. Are you >>> arguing that there is no difference in coupling between using a >>> Singletong and a Just Create One? >>> >>> Curious, Ilja >> >> >> Coupling, shmupling. No, I'm saying that there is little difference >> in building an entire design around a JCO by convention vs. building >> an entire design around a JCO by fiat. > > Is "JCO by fiat" the Singleton pattern here? If not, you managed to > confuse me even more... ;) > > BTW, I think that the whole point of JCO is that it's exactly *not* > the entire design that is build around it. Actually almost all of its > clients don't know about the number of instances.
I suppose that's true. If JCO means that the JCO instance is passed around like any other instance, and that the users of that reference don't particularly regard it as any different than any other instance, with no assumption as to whether it is only one or one of many, then I suppose you're right. Tight coupling is avoided, as you suggested.
However, I still just can't get worked up over how hard it is to refactor a singleton hierarchy into a multi-ton :), should the need arise later. And I just can't imagine that the cases where it /does/ prove to be extraordinarily difficult are all that common.
> >> Like I said before: "eh." > > Yes, you keep saying. Doesn't seem to help me understand your point, > though...
Ok, maybe "bah" then ? :)
-- Framsticks. 3D Artificial Life evolution. You can see the creatures that evolve and how they interact, hunt, swim, etc. (Unaffiliated with me). http://www.frams.alife.pl/
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Thu, 20 Jan 2005 22:38:01 +0100 |
|
|
 | Thomas G. Marshall wrote:
> I suppose that's true. If JCO means that the JCO instance is passed > around like any other instance, and that the users of that reference > don't particularly regard it as any different than any other > instance, with no assumption as to whether it is only one or one of > many, then I suppose you're right. Tight coupling is avoided, as you > suggested.
Exactly! :)
> However, I still just can't get worked up over how hard it is to > refactor a singleton hierarchy into a multi-ton :), should the need > arise later.
When the Singleton is referenced from a trillion places in the system, it's surprisingly much work. And it's quite easy to turn up with such a system once you introduced the Singleton, in my experience...
> And I just can't imagine that the cases where it /does/ > prove to be extraordinarily difficult are all that common.
Actually it's already more difficult to simply unit test a client of a Singleton than I'd like it to be. YMMV, of course.
Cheers, Ilja
|
|
 | | From: | Calum Grant | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 16:15:31 GMT |
|
|
 | Ilja Preuß wrote: > http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne > > Cheers, Ilja > >
Ah, yes. I agree pretty whole-heartedly with that article. Passing the objects you need around the program is much better design IMHO. Singletons are a throw-back from procedural programming when global variables were hard to avoid.
Calum
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 00:26:12 +0100 |
|
|
 | Kent Beck's "Test Driven Development - By Example" also has a chapter on Design Patterns. My favorite is the entry on Singleton:
"How do you provide global variables in languages without global variables? Don't. Your programs will thank you for taking the time to think about design instead."
Cheers, Ilja
|
|
 | | From: | iamfractal at hotmail.com | | Subject: | Re: Singletons | | Date: | 20 Jan 2005 00:17:48 -0800 |
|
|
 | Doc O'Leary wrote: > In article <41ed86f8@news.totallyobjects.com>, > "Ilja Preu=DF" wrote:
Snip, snip.
> > Perhaps. My other related point is that since a class object *is* a > singleton, I question the need of creating an instance at all when the > class itself is just sitting there to use without having to pretend to > create a new instance object. Consider, for example, prototype-based OO > languages where there is no distinction between classes and instances. > In that kind of environment, *any* object in the global scope that > doesn't serve as a prototype for other objects can be considered a > singleton. But that is not in any way "special" in a manner that > suggest it should be avoided.
(I love this thread.)
Just on that point, in languages that distinguish between class and object, it can be useful to create the single instance rather than offer class-based access.
For example, in Java (yeah, yeah, I can hear the groans), static methods can't be overridden by subclasses, so polymorphism gets a luxury holiday in Guantanamo Bay.
(Though, strictly-speaking, a Singleton's private constructor also famously makes it unsubclassable in Java, so I personally skip that bit, which exposes Singletons to neglect from within their package; more engineering compromise.) ..ed
www.EdmundKirwan.com - Home of The Fractal Class Composition.
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 14:37:47 GMT |
|
|
 | iamfractal@hotmail.com coughed up: > Doc O'Leary wrote: >> In article <41ed86f8@news.totallyobjects.com>, >> "Ilja Preuß" wrote: > > Snip, snip. > >> >> Perhaps. My other related point is that since a class object *is* a >> singleton, I question the need of creating an instance at all when >> the class itself is just sitting there to use without having to >> pretend to create a new instance object. Consider, for example, >> prototype-based OO languages where there is no distinction between >> classes and instances. In that kind of environment, *any* object in >> the global scope that doesn't serve as a prototype for other objects >> can be considered a singleton. But that is not in any way "special" >> in a manner that suggest it should be avoided. > > (I love this thread.)
It has its plusses...
> Just on that point, in languages that distinguish between class and > object, it can be useful to create the single instance rather than > offer class-based access. > > For example, in Java (yeah, yeah, I can hear the groans),
Whoa, perspective check: the groans I hear about java usually come from OO purists. They flock to c.o certainly, but they often disagree on so much regarding other languages that it hardly makes any groans here particularly poignant.
....[rip]...
-- "So I just, uh... I just cut them up like regular chickens?" "Sure, just cut them up like regular chickens."
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 12:50:45 -0600 |
|
|
 | In article , Calum Grant wrote:
> So my point is this: singletons should be discouraged, even banned.
That is a very short-sighted opinion. Bad coding styles abound, whether they contain OO singletons/globals or not. What I don't see being discussed in this thread is how classes themselves, especially in languages where classes are themselves objects, can be considered singletons. Are you really calling for a ban on classes? Or possibly even a ban on namespaces? The deeper question really seems to be that of resource location, and if you propose to ban global identifiers you had damn well better propose an alternative that makes more sense for the developer. Until you do, consider your opinion considered and rejected.
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 23:32:59 +0100 |
|
|
 | Doc O'Leary wrote:
> Bad coding styles abound, > whether they contain OO singletons/globals or not.
Well, yes. That's hardly a good argument *for* the use of Singletons, though.
> What I don't see > being discussed in this thread is how classes themselves, especially > in languages where classes are themselves objects, can be considered > singletons.
I don't think they cause as much trouble as object Singletons, but actually there are reasons for the existence of principles like "program to an interface" and patterns like Abstract Factory.
> Are you really calling for a ban on classes? Or possibly > even a ban on namespaces?
Just because you think that those things have something in common doesn't mean that from the OPs point of view they cause the same kind of trouble, does it?
Cheers, Ilja
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Mon, 17 Jan 2005 11:22:42 -0600 |
|
|
 | In article <41eaeeeb@news.totallyobjects.com>, "Ilja Preuß" wrote:
> Doc O'Leary wrote: > > > Bad coding styles abound, > > whether they contain OO singletons/globals or not. > > Well, yes. That's hardly a good argument *for* the use of Singletons, > though.
I was not arguing in favor of singletons, but rather *against* a campaign to focus on them as a major problem.
> > Are you really calling for a ban on classes? Or possibly > > even a ban on namespaces? > > Just because you think that those things have something in common doesn't > mean that from the OPs point of view they cause the same kind of trouble, > does it?
It should. It is inconsistent to consider a singleton bad because it is "global" yet somehow gloss over other objects that have a global scope. The only reason a singleton can be considered global is because the *class* returning it is global. That would be were to address the issue, and in a more significant way that "just say no".
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Mon, 17 Jan 2005 22:35:56 +0100 |
|
|
 | Doc O'Leary wrote: > It is inconsistent to consider a singleton bad because it > is "global" yet somehow gloss over other objects that have a global > scope.
Class instances are used for other things and in other ways than the other "objects" you mentioned, and therefore globality does cause different (in my opinion more) problems. No inconsistency or glossing over involved, as far as I can see.
Take care, Ilja
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 12:39:31 -0600 |
|
|
 | In article <41ec330b$1@news.totallyobjects.com>, "Ilja Preuß" wrote:
> Doc O'Leary wrote: > > It is inconsistent to consider a singleton bad because it > > is "global" yet somehow gloss over other objects that have a global > > scope. > > Class instances are used for other things and in other ways than the other > "objects" you mentioned, and therefore globality does cause different (in my > opinion more) problems. No inconsistency or glossing over involved, as far > as I can see.
Just because you choose to *use* them differently doesn't *make* them different. A class *is* global, whether it makes one instance, two instances (e.g., a boolean), or any number of otherwise uniqued instances (e.g., immutable strings). Worrying about the details of what sort of instance gets returned is ludicrous. All I'm asking is that you argue against the right thing, and it seems to me that singletons are *not* the root of whatever issue is being raised.
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Fri, 21 Jan 2005 00:46:28 GMT |
|
|
 | Doc O'Leary coughed up: > In article <41ec330b$1@news.totallyobjects.com>, > "Ilja Preuß" wrote: > >> Doc O'Leary wrote: >>> It is inconsistent to consider a singleton bad because it >>> is "global" yet somehow gloss over other objects that have a global >>> scope. >> >> Class instances are used for other things and in other ways than the >> other "objects" you mentioned, and therefore globality does cause >> different (in my opinion more) problems. No inconsistency or >> glossing over involved, as far as I can see. > > Just because you choose to *use* them differently doesn't *make* them > different. A class *is* global, whether it makes one instance, two > instances (e.g., a boolean), or any number of otherwise uniqued > instances (e.g., immutable strings). Worrying about the details of > what sort of instance gets returned is ludicrous. All I'm asking is > that you argue against the right thing, and it seems to me that > singletons are *not* the root of whatever issue is being raised.
Well, as you can tell from my other posts here, I too think this concern over singletons is a little silly.
But in all honesty, I don't think your logic tracks here precisely. A singleton is something created by the engineer with a specific purpose: to be only one. A class, while there is only one, has a much greater use in stamping out multiple instances. To say that all class access is fraught with the precise same implications as singleton use is not entirely true. That is, you can get rid of all singletons---you can't get rid of all classes----/those/ are irreplaceable (except for oddball OOPL's).
But then (again), I don't think /any/ of this is an issue.
-- "His name was Robert Paulson. His name was Robert Paulson. His name was Robert Paulson..."
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Fri, 21 Jan 2005 15:05:36 -0600 |
|
|
 | In article , "Thomas G. Marshall" wrote:
> But in all honesty, I don't think your logic tracks here precisely. A > singleton is something created by the engineer with a specific purpose: to > be only one. A class, while there is only one, has a much greater use in > stamping out multiple instances.
But that's why my logic tracks so very well! Just because a class can conceptually produce many instances is irrelevant in the case of a singleton. For that, you have precisely one class object and one instance object, leaving me to wonder why you need the instance object at all.
> But then (again), I don't think /any/ of this is an issue.
Likewise. I don't have have any real problem with a class/instance "duality" singleton because there are, as others have noted, some OO languages that treat class objects differently. For my own uses, though, I prefer to use the class object as the singleton and forego all the unnecessary busywork of maintaining a single instance as well.
|
|
 | | From: | Thomas Gagne | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 10:43:06 -0500 |
|
|
 |
Doc O'Leary wrote:
> > > Likewise. I don't have have any real problem with a class/instance > "duality" singleton because there are, as others have noted, some OO > languages that treat class objects differently. For my own uses, > though, I prefer to use the class object as the singleton and forego all > the unnecessary busywork of maintaining a single instance as well.
That seems to make sense, and would be very easy to do in Smalltalk, but I haven't noticed it as an idiom and didn't find it in the index of Beck's "Best Practice Patterns."
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 18:09:34 +0100 |
|
|
 | Thomas Gagne wrote: > That seems to make sense, and would be very easy to do in Smalltalk, > but I haven't noticed it as an idiom and didn't find it in the index > of Beck's "Best Practice Patterns."
Very good book!
From his "Test Driven Development - by Example" book, it becomes quite clear that Beck doesn't like Singletons.
Cheers, Ilja
|
|
 | | From: | Thomas Gagne | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 10:49:29 -0500 |
|
|
 | Ilja Preuß wrote: > Thomas Gagne wrote: >
> From his "Test Driven Development - by Example" book, it becomes quite clear > that Beck doesn't like Singletons.
Is that because he doesn't like singletons or because it's easier to use class variables?
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 17:22:27 +0100 |
|
|
 | Thomas Gagne wrote: > Ilja Preuß wrote: >> Thomas Gagne wrote: >> > >> From his "Test Driven Development - by Example" book, it becomes >> quite clear that Beck doesn't like Singletons. > > Is that because he doesn't like singletons or because it's easier to > use class variables?
The book has a chapter on a number of design patterns, with approximately one page per pattern.
Singleton is the only exception. Kent Beck writes about it: "How do you provide global variables in languages without global variables? Don't. Your programs will thank you for taking the time to think about design instead."
Cheers, Ilja
|
|
 | | From: | Michael Feathers | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 16:28:22 GMT |
|
|
 |
"Ilja Preuß" wrote in message news:41f3d2a0@news.totallyobjects.com... > Thomas Gagne wrote: > > Ilja Preuß wrote: > >> Thomas Gagne wrote: > >> > > > >> From his "Test Driven Development - by Example" book, it becomes > >> quite clear that Beck doesn't like Singletons. > > > > Is that because he doesn't like singletons or because it's easier to > > use class variables? > > The book has a chapter on a number of design patterns, with approximately > one page per pattern. > > Singleton is the only exception. Kent Beck writes about it: "How do you > provide global variables in languages without global variables? Don't. Your > programs will thank you for taking the time to think about design instead."
It's a pretty important point. When you use globals often you miss opportunities to really think about layering.
-- Michael Feathers author, Working Effectively with Legacy Code (Prentice Hall 2005) www.objectmentor.com
|
|
 | | From: | Roger L. Cauvin | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 11:00:44 -0600 |
|
|
 | "Thomas Gagne" wrote in message news:OIydnSZDwsIZWm7cRVn-gw@wideopenwest.com... > Ilja Preuß wrote: >> Thomas Gagne wrote: >> > >> From his "Test Driven Development - by Example" book, it >> becomes quite clear that Beck doesn't like Singletons. > > Is that because he doesn't like singletons or because it's easier > to use class variables?
Thomas, I think you need to reflect on your tendency to rationalize away quotes from authoritative sources. As another reply in this message implies, Beck suggests avoiding singletons, class variables, and anything resembling a global variable.
In a singleton thread a couple of years ago, you attempted to rationalize away the following quote from Ralph Johnson, one of the original GoF who wrote the DESIGN PATTERNS book:
"Singleton is a weak pattern, and whenever people start with Singleton, it is a sign of a bad design."
At the time, you chose to escape as follows:
"Dr. Johnson was speaking in the context of designing a GUI. I'm unsure if a single sentence applies to everything."
Recognize your own rationalization "pattern"?
-- Roger L. Cauvin nospam_roger@cauvin.org (omit the "nospam_" part) Cauvin, Inc. http://www.cauvin-inc.com
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Mon, 24 Jan 2005 04:27:38 GMT |
|
|
 | Roger L. Cauvin coughed up: > "Thomas Gagne" wrote in message > news:OIydnSZDwsIZWm7cRVn-gw@wideopenwest.com... >> Ilja Preuß wrote: >>> Thomas Gagne wrote: >>> >> >>> From his "Test Driven Development - by Example" book, it >>> becomes quite clear that Beck doesn't like Singletons. >> >> Is that because he doesn't like singletons or because it's easier >> to use class variables? > > Thomas, I think you need to reflect on your tendency to rationalize > away quotes from authoritative sources. As another reply in this > message implies, Beck suggests avoiding singletons, class variables, > and anything resembling a global variable. > > In a singleton thread a couple of years ago, you attempted to > rationalize away the following quote from Ralph Johnson, one of the > original GoF who wrote the DESIGN PATTERNS book: > > "Singleton is a weak pattern, and whenever people start with > Singleton, it is a sign of a bad design." > > At the time, you chose to escape as follows: > > "Dr. Johnson was speaking in the context of designing a GUI. I'm > unsure if a single sentence applies to everything." > > Recognize your own rationalization "pattern"?
I'm not sure that's a real problem. It doesn't sound like rationalization to me; more like simple qualification.
-- Whyowhydidn'tsunmakejavarequireanuppercaselettertostartclassnames....
|
|
 | | From: | Michael Feathers | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 21:47:47 GMT |
|
|
 | "Roger L. Cauvin" wrote in message news:35i3hqF4gfdmbU1@individual.net... > "Thomas Gagne" wrote in message > news:OIydnSZDwsIZWm7cRVn-gw@wideopenwest.com... > > Ilja Preuß wrote: > >> Thomas Gagne wrote: > >> > > > >> From his "Test Driven Development - by Example" book, it > >> becomes quite clear that Beck doesn't like Singletons. > > > > Is that because he doesn't like singletons or because it's easier > > to use class variables? > > Thomas, I think you need to reflect on your tendency to rationalize away > quotes from authoritative sources. As another reply in this message > implies, Beck suggests avoiding singletons, class variables, and anything > resembling a global variable. > > In a singleton thread a couple of years ago, you attempted to rationalize > away the following quote from Ralph Johnson, one of the original GoF who > wrote the DESIGN PATTERNS book: > > "Singleton is a weak pattern, and whenever people start with Singleton, it > is a sign of a bad design." > > At the time, you chose to escape as follows: > > "Dr. Johnson was speaking in the context of designing a GUI. I'm unsure if a > single sentence applies to everything." > > Recognize your own rationalization "pattern"?
I don't really mind that. Things are true or false independently of whether someone famous said it.
-- Michael Feathers author, Working Effectively with Legacy Code (Prentice Hall 2005) www.objectmentor.com
|
|
 | | From: | Thomas Gagne | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 17:26:16 -0500 |
|
|
 | Roger L. Cauvin wrote:
> > Thomas, I think you need to reflect on your tendency to rationalize away > quotes from authoritative sources. As another reply in this message > implies, Beck suggests avoiding singletons, class variables, and anything > resembling a global variable.
I was actually curious and not trying to trivialize the advice. If he ignored a pattern I thought he may have provided an alternative, or suggested it wasn't necessary given another idiom, or that there may be some other explanation. The quote given was a pleasant platitude but doesn't provide any rationalization of its own (I don't have the book so can't look up its context). > > In a singleton thread a couple of years ago, you attempted to rationalize > away the following quote from Ralph Johnson, one of the original GoF who > wrote the DESIGN PATTERNS book: > > "Singleton is a weak pattern, and whenever people start with Singleton, it > is a sign of a bad design." > > At the time, you chose to escape as follows: > > "Dr. Johnson was speaking in the context of designing a GUI. I'm unsure if a > single sentence applies to everything." > > Recognize your own rationalization "pattern"? >
Go figure. I could write my own patterns book!
Regardless of the authority (though I admit a tendency to give their words more weight than others') I think it's inadequate to simply say something is fundamentally bad without some exposition on why.
I've used singletons twice in five years. The simplest to explain is a class that wraps standard-io for Smalltalk. To access the standard IO streams, which could be accessed nearly anywhere by anyone, a simple "EfStdIO default stdout" would return the standard output stream. There are advantages to having it be an instance as it relates to construction and destruction of the streams than implementing everything as a class method or having multiples of them.
So I'm still wondering about the rules, which ones I may have violated, and how much time I may have wasted looking for something other than a singleton had I read advice warning they were evil, when perhaps they were the simlest correct thing.
I'll have to reread that thread to rediscover if Dr. Johnson meant that a Singleton was an indicator of bad design anywhere it might be used.
As was noted earlier in this thread, there are lots of globals in language environments (classes, namespaces), in logical address spaces (any named address, function, etc.), and on computers. There must be a better rule than "all the globals that exist are all that ever need exist and any you feel necessary are not." That smells a lot like language design philosophies that prohibit extending classes or overriding methods. Few designs are so perfectly conceived and implemented.
|
|
 | | From: | Thomas G. Marshall | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 14:55:16 GMT |
|
|
 | Doc O'Leary coughed up: > In article , > "Thomas G. Marshall" > wrote: > >> But in all honesty, I don't think your logic tracks here precisely. >> A singleton is something created by the engineer with a specific >> purpose: to be only one. A class, while there is only one, has a >> much greater use in stamping out multiple instances. > > But that's why my logic tracks so very well! Just because a class can > conceptually produce many instances is irrelevant in the case of a > singleton. For that, you have precisely one class object and one > instance object, leaving me to wonder why you need the instance object > at all. > >> But then (again), I don't think /any/ of this is an issue. > > Likewise. I don't have have any real problem with a class/instance > "duality" singleton because there are, as others have noted, some OO > languages that treat class objects differently. For my own uses, > though, I prefer to use the class object as the singleton and forego > all the unnecessary busywork of maintaining a single instance as well.
I've seen that a lot. I (too) don't see a hell of a lot of difference between
Singleton.instance.hoohah();
and
Singleton.hoohah();
With the exception that the former Singleton.instance can be passed about like a normal instance where the latter cannot in most OOPL's I think. JCO arguments aside.
-- "So I just, uh... I just cut them up like regular chickens?" "Sure, just cut them up like regular chickens."
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 17:58:57 +0100 |
|
|
 | Thomas G. Marshall wrote: > I (too) don't see a hell of a lot of difference > between > > Singleton.instance.hoohah(); > > and > > Singleton.hoohah(); > > With the exception that the former Singleton.instance can be passed > about like a normal instance where the latter cannot in most OOPL's I > think.
And Singleton.instance could actually give us an instance of a *subclass* of Singleton, without the clients noticing. Often that is the only way to make the clients of a Singleton testable.
Cheers, Ilja
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Sat, 22 Jan 2005 17:38:04 -0600 |
|
|
 | In article <41f289ad$1@news.totallyobjects.com>, "Ilja Preuß" wrote:
> Thomas G. Marshall wrote: > > > > With the exception that the former Singleton.instance can be passed > > about like a normal instance where the latter cannot in most OOPL's I > > think.
Sure, but the shortcomings of an implementation language should not handicap a good design. Abstractly a singleton is "just one", and if you happen to be using an environment that can appropriately represent that with one (class) object, it makes no sense to complicate the implementation by using an unnecessary instance.
> And Singleton.instance could actually give us an instance of a *subclass* of > Singleton, without the clients noticing.
The same can be accomplished in OO environments that allow classes to pose as other classes. It also means it can also be done without changing the first class at all, whereas your way would force the it to know about the subclass in order to return its instance. Again, when possible, it seems just using the class as the singleton directly is a better approach.
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Sun, 23 Jan 2005 01:41:36 +0100 |
|
|
 | Doc O'Leary wrote:
>> And Singleton.instance could actually give us an instance of a >> *subclass* of Singleton, without the clients noticing. > > The same can be accomplished in OO environments that allow classes to > pose as other classes.
As I said, I've never worked in such a language, so I can't comment.
Cheers, Ilja
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 22:46:03 +0100 |
|
|
 | Doc O'Leary wrote: > In article <41ec330b$1@news.totallyobjects.com>, > "Ilja Preuß" wrote: > >> Doc O'Leary wrote: >>> It is inconsistent to consider a singleton bad because it >>> is "global" yet somehow gloss over other objects that have a global >>> scope. >> >> Class instances are used for other things and in other ways than the >> other "objects" you mentioned, and therefore globality does cause >> different (in my opinion more) problems. No inconsistency or >> glossing over involved, as far as I can see. > > Just because you choose to *use* them differently doesn't *make* them > different.
But how I use something changes what properties I want it to have, and what properties present a problem for me.
Both my old CD-ROM drive and my hifi system are quite loud. I think it's much more of a problem for the former.
> A class *is* global, whether it makes one instance, two > instances (e.g., a boolean), or any number of otherwise uniqued > instances (e.g., immutable strings).
Yes, it is. I don't see your point though. Perhaps you'd like to explain how that property of a class leads to the same problems the globality of the access point to the single instance of a Singleton does.
> Worrying about the details of > what sort of instance gets returned is ludicrous.
I can't identify with that statement, mostly because I don't understand it. But I have the gut feel that you misunderstand what I dislike about the Singleton pattern.
> All I'm asking is > that you argue against the right thing, and it seems to me that > singletons are *not* the root of whatever issue is being raised.
The *root* of the issue - to me - is an overly coupled design that makes a system hard to change. The singleton pattern is just a very specific incarnation of that problem, one that is prominent enough to be discussed explicitely, in my opinion.
Take care, Ilja
|
|
 | | From: | Doc O'Leary | | Subject: | Re: Singletons | | Date: | Wed, 19 Jan 2005 15:27:45 -0600 |
|
|
 | In article <41ed86f8@news.totallyobjects.com>, "Ilja Preuß" wrote:
> Doc O'Leary wrote: > > > > Just because you choose to *use* them differently doesn't *make* them > > different. > > But how I use something changes what properties I want it to have, and what > properties present a problem for me.
No it doesn't! We're talking about a singleton here. If you have reason to use it differently, it should not be the same object. That would mean the real issue is you using singletons where they are not the correct solution.
> Both my old CD-ROM drive and my hifi system are quite loud. I think it's > much more of a problem for the former.
I don't understand this example.
> > A class *is* global, whether it makes one instance, two > > instances (e.g., a boolean), or any number of otherwise uniqued > > instances (e.g., immutable strings). > > Yes, it is. I don't see your point though. Perhaps you'd like to explain how > that property of a class leads to the same problems the globality of the > access point to the single instance of a Singleton does.
I can't explain because I don't see a singleton as a problem. You do, so you it is on your shoulder to explain why access to a single instance is bad, but access to the *class* of that instance, something that is usually necessary to *get* that singleton, is not bad.
> > Worrying about the details of > > what sort of instance gets returned is ludicrous. > > I can't identify with that statement, mostly because I don't understand it. > But I have the gut feel that you misunderstand what I dislike about the > Singleton pattern.
Perhaps. My other related point is that since a class object *is* a singleton, I question the need of creating an instance at all when the class itself is just sitting there to use without having to pretend to create a new instance object. Consider, for example, prototype-based OO languages where there is no distinction between classes and instances. In that kind of environment, *any* object in the global scope that doesn't serve as a prototype for other objects can be considered a singleton. But that is not in any way "special" in a manner that suggest it should be avoided.
|
|
 | | From: | Ilja Preuß | | Subject: | Re: Singletons | | Date: | Thu, 20 Jan 2005 14:32:11 +0100 |
|
|
 | Doc O'Leary wrote: > In article <41ed86f8@news.totallyobjects.com>, > "Ilja Preuß" wrote: > >> Doc O'Leary wrote: >>> >>> Just because you choose to *use* them differently doesn't *make* >>> them different. >> >> But how I use something changes what properties I want it to have, >> and what properties present a problem for me. > > No it doesn't! We're talking about a singleton here.
Sorry for not being clear - I'm talking about the fact that just because being global is a problem for a class instance, it doesn't mean that being global is a similarly big problem for everything else, too.
>> Both my old CD-ROM drive and my hifi system are quite loud. I think >> it's much more of a problem for the former. > > I don't understand this example.
Reconsider in the light of the above clarification.
>>> A class *is* global, whether it makes one instance, two >>> instances (e.g., a boolean), or any number of otherwise uniqued >>> instances (e.g., immutable strings). >> >> Yes, it is. I don't see your point though. Perhaps you'd like to >> explain how that property of a class leads to the same problems the >> globality of the access point to the single instance of a Singleton >> does. > > I can't explain because I don't see a singleton as a problem. You do, > so you it is on your shoulder to explain why access to a single > instance > is bad, but access to the *class* of that instance, something that is > usually necessary to *get* that singleton, is not bad.
When using JCO instead of Singleton, a client doesn't access anything global, but is given the instance to work with from the outside. That reduces coupling and thereby increases flexibility.
> Perhaps. My other related point is that since a class object *is* a > singleton, I question the need of creating an instance at all when the > class itself is just sitting there to use without having to pretend to > create a new instance object.
Well, sort of. In some languages, like Java, using class methods provides even less flexibility, because they aren't polymorphic.
Directly using class methods, though, certainly presents similar problems to those of the Singleton pattern, namely a coupling of the client to that particular class.
> Consider, for example, prototype-based > OO languages where there is no distinction between classes and > instances. > In that kind of environment, *any* object in the global scope that > doesn't serve as a prototype for other objects can be considered a > singleton. But that is not in any way "special" in a manner that > suggest it should be avoided.
Sorry, I don't know enough about prototype based languages to comment.
Cheers, Ilja
|
|
 | | From: | Andrew McDonagh | | Subject: | Re: Singletons | | Date: | Tue, 18 Jan 2005 19:43:04 +0000 |
|
|
 | Doc O'Leary wrote: > In article <41ec330b$1@news.totallyobjects.com>, > "Ilja Preuß" wrote: > > >>Doc O'Leary wrote: >> >>>It is inconsistent to consider a singleton bad because it >>>is "global" yet somehow gloss over other objects that have a global >>>scope. >> >>Class instances are used for other things and in other ways than the other >>"objects" you mentioned, and therefore globality does cause different (in my >>opinion more) problems. No inconsistency or glossing over involved, as far >>as I can see. > > > Just because you choose to *use* them differently doesn't *make* them > different. A class *is* global, whether it makes one instance, two > instances (e.g., a boolean), or any number of otherwise uniqued > instances (e.g., immutable strings). Worrying about the details of what > sort of instance gets returned is ludicrous. All I'm asking is that you > argue against the right thing, and it seems to me that singletons are > *not* the root of whatever issue is being raised.
You are right...
Right in that Singletons are not bad - and most replies have stated that we don't consider Singletons to be wrong/bad/evil/etc.
However, most replies have shown the misuse of Singletons, and its this misuse which is bad/wrong/evil/etc.
Personally, if a design merits a Singleton then I will use a Singleton, but I will want to be completely sure that it is ABSOLUTELY VITAL that only a single instance of the class can exist. I certainly won't use a singleton because we ONLY need a single instance today, nor will I use a Singleton because its static access method makes it easier to get to it.
|
|
 | | From: | Andrew McDonagh | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 19:34:56 +0000 |
|
|
 | Calum Grant wrote: > I quite often see singletons in code, and I think they are overused. > > Singletons have the disadvantage that everyone in the whole world has > access to that object, which is as bad as a global function. Anyone can > call a singleton and create havoc on it. > > Singletons also introduce hard-coded dependencies that are difficult to > break if one wishes to change the environment or reuse some of the > classes in a different project. > > Just because you call something a "singleton" instead of a global > variable does not make it a good pattern. > > Singletons are lazy design, since "global scope" is too broad a scope > for most objects. > > So my point is this: singletons should be discouraged, even banned. > > Calum
Whilst I understand the need for the pattern and have used it once or twice myself, I fully agree with you. The JustCreateOne alternative can have a much better effect upon the code base and its design.
Just this week, I've been refactoring a huge section of code to rid it of a singleton, because we now need two instances of the class in the system. The fact that we never did actually need to prevent more than one instance before, is a classic example of the developers choosing a singleton, not because its appropriate, but because it was easier to have a global object and its static getInstance() method.
The situation was actually worse, in that the guys needing to have a second instance of the object around, but not being able to see an easy way of refactoring the singleton away. So they made a public setInstance() method to accompany its getInstance(). :-)
|
|
 | | From: | smilemac | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 18:50:38 +0800 |
|
|
 | "Andrew McDonagh" wrote in message news:csbr93$2vr$1@news.freedom2surf.net... > Calum Grant wrote: > > I quite often see singletons in code, and I think they are overused. > > > > Singletons have the disadvantage that everyone in the whole world has > > access to that object, which is as bad as a global function. Anyone can > > call a singleton and create havoc on it. > > > > Singletons also introduce hard-coded dependencies that are difficult to > > break if one wishes to change the environment or reuse some of the > > classes in a different project. > > > > Just because you call something a "singleton" instead of a global > > variable does not make it a good pattern. > > > > Singletons are lazy design, since "global scope" is too broad a scope > > for most objects. > > > > So my point is this: singletons should be discouraged, even banned. > > > > Calum > > Whilst I understand the need for the pattern and have used it once or > twice myself, I fully agree with you. The JustCreateOne alternative can > have a much better effect upon the code base and its design. > > Just this week, I've been refactoring a huge section of code to rid it > of a singleton, because we now need two instances of the class in the > system. The fact that we never did actually need to prevent more than > one instance before, is a classic example of the developers choosing a > singleton, not because its appropriate, but because it was easier to > have a global object and its static getInstance() method. > > The situation was actually worse, in that the guys needing to have a > second instance of the object around, but not being able to see an easy > way of refactoring the singleton away. So they made a public > setInstance() method to accompany its getInstance(). :-)
Could you give more details about why it's not easy to refactor? Why you cannot just remove the "modifiers" for singleton, such as "static", "private/protected" and etc. ? What purpose is the "setInstance", to reset the instance as null? If so, I think your first version design should have some problems.
smilemac
|
|
 | | From: | Andrew McDonagh | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 13:21:47 +0000 |
|
|
 | smilemac wrote: > "Andrew McDonagh" wrote in message
snipped.
>> >>Whilst I understand the need for the pattern and have used it once or >>twice myself, I fully agree with you. The JustCreateOne alternative can >>have a much better effect upon the code base and its design. >> >>Just this week, I've been refactoring a huge section of code to rid it >>of a singleton, because we now need two instances of the class in the >>system. The fact that we never did actually need to prevent more than >>one instance before, is a classic example of the developers choosing a >>singleton, not because its appropriate, but because it was easier to >>have a global object and its static getInstance() method. >> >>The situation was actually worse, in that the guys needing to have a >>second instance of the object around, but not being able to see an easy >>way of refactoring the singleton away. So they made a public >>setInstance() method to accompany its getInstance(). :-) > > > Could you give more details about why it's not easy to refactor?
It was so much as hard to refactor, but time consuming just because of the number of classes using the singleton. The hard-ish part was looking at the code and deciding how these classes could get access to 'an' instance of the class, rather than 'theSingleton' instance.
Some questions we asked ourselves were... #Should the instance be passed directly to them? #Should they get() it from another object they already had access too? #Should we use a Register type pattern to still have global access, not to the singleton object, but to a Registry of these objects, keyed off some value? #etc.
In the end we decided with the current design the easiest, quickest, smartest approach was for the objects to get() 'an' instance of the singleton from an associated object.
>Why you > cannot just remove the "modifiers" for singleton, such as "static", > "private/protected" and etc. ?
The code using the public static access method : getInstance() is spread around the code base. Depending upon the context the client classes are in, they all needed to perform actions upon the same instance of the object which currently is a singleton. However, there was never any need for a singleton. The same set of client classes, with a different context, are need to perform the same work but on the different instance of the class which is currently a singleton.
There's now only a 3 classes( and their tests) still to change. Once they have been refactored, we will be free to simply remove the static getInstance() method from the singleton class, and simply 'new' an instance whenever and wherever we need too.
What purpose is the "setInstance", to reset > the instance as null? If so, I think your first version design should have > some problems. >
It simply changed the object that was returned via the getInstance() method - basically to 'allow' a second instance of the singleton class to exist.
This was a band aid 'fix' to enable the new requirement to be implemented, without having to spend time refactoring the original design which inappropriately used a singleton.
The original design inappropriately used a singleton, because it was the simplest and quickest thing to do. We initially saved some development time. Then as soon as we had a new requirement that needed another instance of the same class, we 'fixed' the situation with a band aid. However, this just meant that the cost of refactoring away the singleton, was now increased further, as there was now more code using it.
Its my estimation that the time its taken me and my pair to refactor away the singleton, is at least twice that what it would have been to not use it in the first place, regardless of the extra code generated for the second requirement, that also needed to be refactored.
All of this, because the Singleton was used, not for its purpose of controlling instances of the class, but for its global access point method: getInstance().
|
|
 | | From: | smilemac | | Subject: | Re: Singletons | | Date: | Sun, 16 Jan 2005 00:41:12 +0800 |
|
|
 | "Calum Grant" wrote in message news:juaGd.83$VQ5.73@newsfe1-gui.ntli.net... > I quite often see singletons in code, and I think they are overused. > > Singletons have the disadvantage that everyone in the whole world has > access to that object, which is as bad as a global function. Anyone can > call a singleton and create havoc on it. > > Singletons also introduce hard-coded dependencies that are difficult to > break if one wishes to change the environment or reuse some of the > classes in a different project. > > Just because you call something a "singleton" instead of a global > variable does not make it a good pattern. > > Singletons are lazy design, since "global scope" is too broad a scope > for most objects. > > So my point is this: singletons should be discouraged, even banned.
There are many things be singleton, such as log, your application instance, your frame window and etc. If you were worrying about the visible scope. You could use a mediator or proxy to keep it in house. Dose it help?
smilemac
|
|
 | | From: | Calum Grant | | Subject: | Re: Singletons | | Date: | Sat, 15 Jan 2005 17:47:53 GMT |
|
|
 | smilemac wrote: > "Calum Grant" wrote in message > news |
|
|