Psuedo Singleton, or other options?

I am working on a project in which I am going to need to reuse a lot of the functionality of some existing singletons in the code base of my company's application.

There are ligitimate reasons for these objects to be singletons (i.e. they store data that I only want stored once, etc). But, in order to reuse the functionality, I need to subclass those objects, hence breaking the "Singletonness" (sorry, I couldn't think of a better word).

I suppose that I could document the class appropriately that hopefully other developers on the project understand not to call the constructor, but rather to use getInstance. And I could probably throw an UnsupportedOperationException on operations that I want public but don't want inheritted.

But this seems kind of ugly and bound to cause future problems. Has anybody found a more elegant solution to such a situation before? Any ideas would be great.

Thanks!

- Adam

[949 byte] By [guitar_man_Fa] at [2007-10-2 21:46:53]
# 1

> I am working on a project in which I am going to need

> to reuse a lot of the functionality of some existing

> singletons in the code base of my company's

> application.

>

> There are ligitimate reasons for these objects to be

> singletons (i.e. they store data that I only want

> stored once, etc). But, in order to reuse the

> functionality, I need to subclass those objects,

> hence breaking the "Singletonness" (sorry, I couldn't

> think of a better word).

Actually, if you read the GoF pattern, the real Singleton pattern's point is to be subclassed.

> I suppose that I could document the class

> appropriately that hopefully other developers on the

> project understand not to call the constructor, but

> rather to use getInstance. And I could probably

> throw an UnsupportedOperationException on operations

> that I want public but don't want inheritted.

Why not declare them final?

> But this seems kind of ugly and bound to cause future

> problems. Has anybody found a more elegant solution

> to such a situation before? Any ideas would be

> great.

If there's a real concern that people will create new instances (and it matters), you can add a volatile static flag to the subclass and check and set it in the constructor. If the constructor get's called when it's set: KABOOM! (that'll teach em.)

dubwaia at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 2
volatile aint enough. Better synchronize. (practically volatile will be enough, but technically it will not)
_dnoyeBa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 3

> volatile aint enough. Better synchronize.

> (practically volatile will be enough, but technically

> it will not)

Sorry, in 1.5 it is enough.Pre 1.5: you are absolutely right. I just came from another thread with the OP where we were discussing this issue. I should have been specific.

dubwaia at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 4
> Sorry, in 1.5 it is enough.Pre 1.5: you are> absolutely right. I just came from another thread> with the OP where we were discussing this issue. I> should have been specific.yes, I understood what you meant, though.- Adam
guitar_man_Fa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 5

> Actually, if you read the GoF pattern, the real

> Singleton pattern's point is to be subclassed.

>

Thank you for point this out. I happen to have a copy of that book, but I hadn't actually read through that section in a while. I've just been so used to declaring the constructor private in singletons. I suppose then, with inheritance, you simply have to take on faith that the programmer extending the singleton is not doing so specifically to circumvent the "singletonness" of the class (i.e. subclassing allows a user to obtain access to the constructor, allowing it to make many copies of that class).

> Why not declare them final?

not only do I not want them overridden, but I don't want them to be able to be called on a sub-class object. I think now, that it would probably make more sense to refactor the common methods into a base class, and split the heirarchy into two branches. That would have the effect I'm looking for. I was trying to avoid creating multiple branches, but in this case, I guess it's better than the alternative.

> If there's a real concern that people will create new

> instances (and it matters), you can add a volatile

> static flag to the subclass and check and set it in

> the constructor. If the constructor get's called

> when it's set: KABOOM! (that'll teach em.)

Actually, that's not a bad idea.

thanks, again.

- Adam

guitar_man_Fa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 6
> > when it's set: KABOOM! (that'll teach em.)> > Actually, that's not a bad idea.Come to think of it, you could do this in the root Singleton class. That would mean people could create only one instance of that type (inclusive of it's children.)
dubwaia at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 7
Volatile != synchronization. Even in 1.5.
_dnoyeBa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 8

> Volatile != synchronization. Even in 1.5.

I never said it was but now I think I am getting your point. Both threads can read the value at the same time. So yeah, a synchronized block is required in the constuctor.

In any event, it's not a big deal because you should only have a one call to the constructor anyway.

dubwaia at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 9

It is always good to use the Double-check locking technique to reduce the usage of synchronization.

class Singleton {

private volatile static Singleton singleton = null;

private Singleton() {}

private static Singleton getObject() {

if (singleton == null) {

synchronized (Singleton.class) {

if (singleton == null) {

singleton = new Singleton();

}

}

}

return singleton;

}

}

Aside, as always I usually discourage using the Singleton design pattern and feel it conflicts with the basics of three-tier programming and building applications with application servers.

For the builders of the group, see more, learn more, feel more at:

http://www.masonicartbook.com

Master_Consultanta at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 10

> It is always good to use the Double-check locking

> technique to reduce the usage of synchronization.

actually, I read a rather interesting article the other day on why double-checked locking is logically flawed. You can find a link to it and a discussion about it on this thread:

http://forum.java.sun.com/thread.jspa?threadID=740910&tstart=0

on the other hand, I really don't see why that's relavent to the discussion, since I am aware of how to ensure the correct number of instances. I simply wasn't sure how one would go about preventing someone from creating multiple copies of a singleton if the constructor was made visible to other classes (say subclasses).

> Aside, as always I usually discourage using the

> Singleton design pattern and feel it conflicts with

> the basics of three-tier programming and building

> applications with application servers.

The company where I work makes FAR too much use of it, in my opinion. However, I do see value in using singletons. When only one instance of an object should be created, and that instance needs to be available to many clients. However, working in a company with many programmers, it's very easy for a programmer who is not familiar with the design to accidentally instantiate a second instance of the class, if that is not guarded against.

> For the builders of the group, see more, learn more,

> feel more at:

> http://www.masonicartbook.com

huh?

guitar_man_Fa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 11

Thanks for the link to the article. I did not study it deeply, but read it briefly. The author does note that the double-check locking strategy does work / can be implemented to work effectively / might work in the future is some cases in a few places.

Extracted from the article for reference -

1. With this change, the Double-Checked Locking idiom can be made to work by declaring the helper field to be volatile.

2. The performance of this technique depends quite a bit on which JDK implementation you have

3. Alexander ... came up with a clever suggestion for implementing double checked locking using thread local storage...

4. It is possible to make the double checked locking pattern work if you have explicit memory barrier instructions.

guitar_man_F states that he sees value in Singleton "When only one instance of an object should be created, and that instance needs to be available to many clients."

It helps to move a bit beyond the basic defintion of the pattern to objectively evaluate the value of the Singleton in todays terms.

My premise is that any design of any software application should directly stem from business/domain requirements. And it is the requirements that mandate what the application does. Now depending upon a set of given requirements, there can many designs to implement them. Some designs can use the Singleton pattern and satisfy the requirements. Ok. The Singleton design pattern can be used in a "good" program. My point is that, based on the same set of requirements, a design can typically be created without using the Singleton design pattern and effectively satisfy the business/domain requirements in an efficient way. In my opinion, I feel that designs that do not use Singleton are more effective and conducive to other elements of the software engineering process, i.e. refactoring, reengineering, code-level conversions to three-tier architectures, and preemptively avoiding other human-related issues such as the one you mention (shown below).

>However, working in a company with many programmers, it's very >easy for a programmer who is not familiar with the design to >accidentally instantiate a second instance of the class, if that is not >guarded against.

Art becomes culture, art is culture, and consumers of culture become one with art.

http://www.masonicartbook.com

Master_Consultanta at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 12
> It is always good to use the Double-check locking> technique to reduce the usage of synchronization. Except that the code you posted is unsafe in any JVM prior to the 1.5 memory model improvements.
dubwaia at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 13

> > It is always good to use the Double-check locking

> > technique to reduce the usage of synchronization.

>

Its never good to use the Double-check locking technique to reduce the usage of synchronization because DCL is fundamentally flawed (not just flawed for Java). The only time DCL seems to work is when its actually not DCL. Such as with Java 1.5 where you are paying the price of synchronization anyway...

_dnoyeBa at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 14

Take a look at the Initialize-on-demand holder pattern for a lazily initialized singleton, which does not require explicit synchronization.

With regards to the original question (protecting a singleton from being constructed inappropriately by subclasses), simply declare your constructor as private. This will prevent subclasses from directly constructing an instance of the singleton.

jonathan.scuddera at 2007-7-14 1:02:30 > top of Java-index,Other Topics,Patterns & OO Design...
# 15

> Take a look at the Initialize-on-demand holder

> pattern for a lazily initialized singleton, which

> does not require explicit synchronization.

Yes yes everyone knows about this.

> With regards to the original question (protecting a

> singleton from being constructed inappropriately by

> subclasses), simply declare your constructor as

> private. This will prevent subclasses from directly

> constructing an instance of the singleton.

You can't subclass a class that has only private constuctors.

dubwaia at 2007-7-21 8:07:50 > top of Java-index,Other Topics,Patterns & OO Design...