Conflicting understanding on singleton implementations - java

From my understanding a Singleton is a single instance of a class that lasts throughout the span of an applications lifetime. However I've seen a few different implementations of the systems, but I'm always informed that they're wrong, flawed, etc. etc. I'm going to post the two that I see more commonly and I would like to hear opinions/fact based on which implementation is better and why. Implementations are compilable.
Implementation A:
public class Foo {
private static Foo singelton;
private Foo() {
System.out.println("Bar");
}
public static Foo getSingleton() {
if(singleton == null) singleton = new Foo();
return singleton;
}
public static void main(String[] args) {
Foo.getSingleton();
}
}
Implementation B:
public class Foo {
private static final Foo singelton = new Foo();
private Foo() {
if(singelton != null) {
throw new IllegalStateException("Singleton class was already constructed.");
}
System.out.println("Bar");
}
public static void main(String[] args) {
// NOT REQUIRED
}
}
You'll notice in Implementation B that the Singleton instance is final. Also, because of the static implementation the main(String[]) method never needs to construct an instance of this class.
Both Implementation A and B will yield the same results.
Opinions?

Hey you have shown two implementations, the second one is called early initialization and first one is called lazy initialization, as it is initializing the class on demand only.
However your first initialization will fail in multi-threaded environment.
You have to use double checked locking to secure your code.
E. g. :
public class EagerSingleton {
private static volatile EagerSingleton instance = null;
// private constructor
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
if (instance == null) {
synchronized (EagerSingleton.class) {
// Double check
if (instance == null) {
instance = new EagerSingleton();
}
}
}
return instance;
}
}
For morer details please check :
http://howtodoinjava.com/2012/10/22/singleton-design-pattern-in-java/

Related

Restrict a class for creating second object in java

Is there a way where we can restrict a class to create only a single object in java? It should give some exceptions if we try to create another new object.
Example:
class A {}
public class Test {
public static void main(String[] args) {
A a1 =new A(); //This should be allowed
A a2 =new A(); // This should not be allowed
}
}
to try your additional requirement:
This should work, but I don't really see a point to it.
public class A {
private static boolean instantiated;
public A() throws Exception {
if ( instantiated ) {
throw new Exception("Already instantiated");
}
instantiated = true;
}
}
You can use the special Singleton pattern. Most of the examples are on the internet.
public class Singleton {
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
}

Stack overflow created by a cycle in code with singletons

I have two singleton classes, lets call them class A and class B.
The classes look like such.
class A
{
private static A instance;
private A(int timeout)
{
init();
}
public static A getInstance(int timeout)
{
if(instance == null)
{
instance = new A(timeout);
}
return instance;
}
private void init()
{
new Monitor().sendMonitorStatus();
}
}
and for class B
class B
{
private static B instance;
private B(A a)
{
}
public static B getInstance(A a)
{
if(instance == null)
{
instance = new B(a);
}
return instance;
}
}
Then there is a class named Monitor as well that looks as such.
class Monitor
{
public void sendMonitorStatus()
{
B.getinstance(A.getinstance(10));
}
}
The problem as you can see, is that I get a stackoverflow since it keeps a cycle of a call to B then calling A which calls B which calls A..., is there anyway to solve this problem without a redesign or is the only way to solve this cycle causing this error to redesign how the classes work?
To create an instance of A, you need to call Monitor::sendMonitorStatus. To call Monitor::sendMonitorStatus, you need an instance of A. You have a dependency cycle.
You need to redesign this. Exactly how – it depends on what you want to achieve.

Clear Singleton instance in Java

I have a Singleton class to save the state of an application's module.
This class simply have a lot of class variables with setters and getters :
public class ModuleState{
private static ModuleState instance;
private A a;
private B b;
private C c;
..
..
..
..
private ModuleState (){}
public ModuleState getInstance(){
if(instance==null)
instance=new ModuleState();
return instance;
}
}
At a precise moment of the application lifecycle, i have the need to CLEAR the module's state. What i do now is to reset ALL the variables in ModuleState by a clearAll() method like this:
public void clearAll(){
a=null;
b=null;
c=null;
..
..
}
My question is the following : there is a cleaner method to do this reset? Possibly clearing the singleton instance itself, without resetting every class variable?
The problem with this approach is that i may have the need to add a new class variable to the ModuleState. In this case i must remember to add a line in the clearAll() method to reset the new variable.
What about ...
public static volatile ModuleState instance = null;
public static void reset() {
instance = new ModuleState();
}
p.s.: as per discussion below: in a multithreaded environment it's very important to synchronize the access on the instance because the JVM is allowed to cache its value. You can use volatile as shown above. Thanks to all!
Cheers!
no, this approach is perfectly acceptable. you are of course synchronizing access to these state objects in some way, right? otherwise you risk someone seeing a half-cleared config object.
another thing you could do to future-proof yourself against any extra state added in the future is store all of your state in a HashMap, for example, instead of individual fields. this way, clear()ing the hashmap ensures that all state is wiped and adding any extra state in the future becomes safer
You need to maintain the same object instance, in order to comply with the Singleton pattern, so your approach makes sense: altering the members.
However, if you wanted to clean it up a little bit, why not just have an internal list, like:
ArrayList<Object> members = new ArrayList<Object>();
// If it actually is Object, there's no need to paramaterize.
// If you want, you can actually make the members implement a common interface,
// and parameterize the ArrayList to that.
Another Option would be to have a HashMap, that binds the key word to the member.
HashMap<String,Object> members = new HashMap<String,Object>();
// Again, same parameterization rules apply.
For an ArrayList or a HashMap, the clearAll method might look like this:
public class ModuleState()
{
public void clearAll()
{
members.clear();
}
}
This method won't need to change.
May be this can help you:
public class SingletonBean {
private static SingletonBean instance = new SingletonBean();
private static Object privateMutex = new Object();
private SingletonBean() {
//to prevent instantiation
}
public class ObjectsContainer {
private Object A;
private Object B;
private Object C;
public Object getA() {
return A;
}
public void setA(Object a) {
A = a;
}
public Object getB() {
return B;
}
public void setB(Object b) {
B = b;
}
public Object getC() {
return C;
}
public void setC(Object c) {
C = c;
}
}
private ObjectsContainer objectsContainer;
private void resetObjectsContainer() {
objectsContainer = new ObjectsContainer();
}
public static SingletonBean getInstance() {
return SingletonBean.instance;
}
public static void clearAll() {
synchronized (privateMutex) {
SingletonBean.getInstance().resetObjectsContainer();
}
}
public static ObjectsContainer getObjectsContainer() {
synchronized (privateMutex) {
return instance.objectsContainer;
}
}
}
public class SomeClass {
public void someMethod() {
SingletonBean.getObjectsContainer().getA();
}
}
Make an inner class to hold the fields, then replace that instance when you want to reset. The write to the field would make the change to all three fields essentially atomic.
public class ModuleState {
private static volatile ModuleState instance;
private static class Values {
A a;
B b;
C c;
}
private volatile Values values = new Values()(
private ModuleState (){}
public ModuleState getInstance(){
if (instance==null) {
synchronized (ModuleState.class) {
if (instance==null) {
instance = new ModuleState();
}
}
}
return instance;
}
public synchronized A getA() {
return values.a;
}
public synchronized void reset() {
values = new Values();
}
By the way, your null checking initialization code was not threadsafe. I fixed that too.
Note that to make this work, you must make the reference to values volatile and synchronize all access to it, otherwise (due to the java memory model) other threads than the one that calls reset() may see the old reference.

How to avoid the creation of object in Java?

I am new to java programming,I have one class,for this class i created two object(obj1,obj2).i don't want to create other than these object,if any body wants to create one more object for this class that should refer to first,or second objects only(instead of creating one more object).how to do this?please refer below code
class B
{
void mymethod()
{
System.out.println("B class method");
}
}
class Myclass extends B
{
public static void main(String s[])
{
B obj1=new B();//this is obj1
B obj2=new B();//this is obj1
B obj3=new B();//don't allow to create this and refer this to obj1 or obj2
}
}
Thanks
azam
Check out the Singleton design pattern.
What you need is the Singleton design pattern.
Class B should look something like so:
class B
{
private static B instance = null;
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
if (instance == null)
{
instance = new B();
}
return instance;
}
}
Then, in your Myclass, just do this:
B obj1 = B.getInstance();
B obj2 = B.getInstance();
Note: This is not thread safe. If you are looking for a thread safe solution please consult the Wiki Page.
EDIT: You could also have a static initializer
class B
{
private static B instance = null;
static
{
instance = new B();
}
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
return instance;
}
}
Yeah singleton it seems the correct way consider the info your providing here.
The default singleton implementation would be the following:
public class Singleton {
//holds single instance reference
private static Singleton instance = null;
//private constructor to avoid clients to call new on it
private Singleton()
{}
public static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
}
Now you can get the single instance of the object by calling :
Singleton instance = Singleton.getInstance();
Keep in mind though that if your working on a threaded enviroment, singleton by default is not thread-safe.
You should make the getInstance method synchronized to avoid unexpected returns.
public synchronized static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
Cheers
Generally speaking you need a singleton pattern. You need to make the constructor to become a private method. Then you create a method to instantiate class B, hence class B can only be instantiated by this method. Have a look at the singleton pattern. It is what you want I believe.
create singleton Class, like
public Class A {
private static Class a = new A();
public A getA() {
return a;
}
}
Object of class A has already created in class A itself. You don't need to create it outside. Just use getA() method to retieve the class A's object.
Like :
A objA = A.getA();
This is called Singlton Pattern.
You can use a Singleton. You have 2 possiblilities for that.
1 . Lazy Creation (Here you make the instance when call the function getInstance() and you check if the instance already exists):
class B {
static private B instance;
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
if (instance == null) {
instance = new B();
}
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
2 . Eager creation (Here you make the instance when the Class is called for the first time):
class B {
static private B instance = new B();
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
be aware, that using a singleton is a big restriction to your code. It can be very annoying when it's not possible to instance more than one object.
Especially when you dont have acces to the source....
The Effective way in multi threaded application, the below logic will may help
public class Singleton {
private static volatile Singleton _instance;
private Singleton(){}
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
I suppose people have not understood the problem statement. It says, not more than 2 objects shall be created. Singleton creates a single object and blocks any further instantiation.
maintain a static variable in ur object class, incrementing by 1 to the upper limit of objects while creating object
when object > bounds needs to be created, select a random number in range[1,bound] and return that object.

Singleton with subclassing in java

The most common way of implementing a singleton in java is to use a private constructor with a public accessor method of the form --
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
However, since the constructor is private, it prevents subclassing the singleton. Is there any way in which we can make a singleton which allows subclassing ?
When you have a class A extends B, an instance of A essentially "includes" instance of B. So the very concept of inheritance is contrary to the singleton model.
Depending on what you need it for, I would consider using composition / delegation. (A would have a reference to the singleton, rather than extending its class). If you need inheritance for some reason, create an interface with the Singleton methods, have Singleton implement that interface, and then have another class also implement that interface, and delegate to the singleton for its implementation of the relevant methods.
If you can inherit it, it's not really a singleton, since each inherited class will have at least one instance.
However, you can just make the constructor protected.
I respectfully offer a counterpoint to the comments that suggest a singleton should not be subclassed. Subclassing a singleton is discussed in "Design Patterns: Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson, and Vlissides (aka "The Gang of Four" book or "GOF" for short).
A properly subclassed singleton would also be a singleton. For example, suppose you have a singleton that handles logging informational messages called Logger. Now suppose you want to extend the functionality of Logger to write output using HTML tags. Let's call it HTMLLogger. Both of these classes are singletons, but one extends the functionality of the other.
First, here's a simple singleton and its test case:
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.simple;
public class SimpleSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static SimpleSingleton instance;
private int sampleValue;
public static SimpleSingleton getInstance() {
if (instance == null) {
instance = new SimpleSingleton();
}
return instance;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected SimpleSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.simple.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.simple.SimpleSingleton;
public class SimpleSingletonTest {
#Test
public void testIllegalCreation() {
// The following line will not compile because the constructor is not visible.
// Singleton instance = new Singleton();
}
#Test
public void testObjectEquality() {
SimpleSingleton instance1 = SimpleSingleton.getInstance();
assertNotNull(instance1);
SimpleSingleton instance2 = SimpleSingleton.getInstance();
assertNotNull(instance2);
assertEquals(instance1, instance2);
}
#Test
public void testDataEquality() {
SimpleSingleton instance1 = SimpleSingleton.getInstance();
assertNotNull(instance1);
SimpleSingleton instance2 = SimpleSingleton.getInstance();
assertNotNull(instance2);
assertEquals(instance1, instance2);
instance1.setSampleValue(5);
int testSampleValue = instance2.getSampleValue();
assertEquals(testSampleValue, 5);
}
}
/////////////////////////////////////////////////////////////////////////////
I've found four ways you can subclass a singleton.
Option 1. Brute force.
Essentially, the subclass reimplements the key features to make the class a singleton. That is, the static instance variable, the static getInstance method, and a hidden constructor. In this case, the hidden constructor calls the base class.
Here's a sample base class, subclass, and test case:
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce;
// This singleton can be extended (subclassed)
public class BruteForceExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static BruteForceExtendableSingleton instance;
private int sampleValue;
public static BruteForceExtendableSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
instance = new BruteForceExtendableSingleton();
}
return instance;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected BruteForceExtendableSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce;
public class BruteForceSubclassSingleton extends BruteForceExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static BruteForceSubclassSingleton instance;
private int sampleValue2;
public static BruteForceSubclassSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
instance = new BruteForceSubclassSingleton();
}
return instance;
}
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
protected BruteForceSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassbruteforce.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassbruteforce.BruteForceExtendableSingleton;
import study.design.patterns.creational.singleton.subclassbruteforce.BruteForceSubclassSingleton;
public class BruteForceExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// BruteForceExtendableSingleton instance = new BruteForceExtendableSingleton();
// BruteForceSubclassSingleton instance2 = new BruteForceSubclassSingleton();
}
#Test
public void testCreateBruteForceExtendableSingleton() {
BruteForceExtendableSingleton singleton = BruteForceExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof BruteForceExtendableSingleton);
assertFalse(singleton instanceof BruteForceSubclassSingleton);
}
#Test
public void testCreateBruteForceSubclassSingleton() {
BruteForceExtendableSingleton singleton = BruteForceSubclassSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a BruteForceSubclassSingleton.
assertTrue(singleton instanceof BruteForceSubclassSingleton);
}
#Test
public void testCreateBothBruteForceSingletons() {
BruteForceExtendableSingleton singleton = BruteForceExtendableSingleton.getInstance();
assertNotNull(singleton);
assertTrue(singleton instanceof BruteForceExtendableSingleton);
assertFalse(singleton instanceof BruteForceSubclassSingleton);
BruteForceExtendableSingleton singleton2 = BruteForceSubclassSingleton.getInstance();
assertNotNull(singleton2);
assertTrue(singleton2 instanceof BruteForceSubclassSingleton);
assertFalse(singleton == singleton2);
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Allows for both singletons to exist at the same time.
Cons:
Duplication of effort to create a singleton. The singleton nature of the subclass does not come from its base class.
If the singletons need to be separate, it's possible that a better design is needed to share the other methods instead of subclassing.
Option 2. Selecting from a fixed set of classes.
In this case, the getInstance method in the base class determines which instance to use based on a flag, such as a system property. In the code sample, I use the name of the class itself. Using a series of if blocks, the code decides how to initialize the instance.
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed;
// This singleton can be extended (subclassed)
public class FixedExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static FixedExtendableSingleton instance;
private int sampleValue;
public static FixedExtendableSingleton getInstance() {
// The problem with this version of an extendable singleton is clear from the code below - every subclass possible is hard-coded.
// Creating a new subclass requires modifying the base class as well, which violates the open-closed principle.
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
if (singletonName.equals(FixedExtendableSingleton.class.getSimpleName())) {
instance = new FixedExtendableSingleton();
} else if (singletonName.equals(FixedSubclassSingleton.class.getSimpleName())) {
instance = new FixedSubclassSingleton();
}
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected FixedExtendableSingleton() {
// Insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed;
public class FixedSubclassSingleton extends FixedExtendableSingleton {
private int sampleValue2;
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected FixedSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassfixed.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassfixed.FixedExtendableSingleton;
import study.design.patterns.creational.singleton.subclassfixed.FixedSubclassSingleton;
public class FixedExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// ExtendableSingleton instance = new ExtendableSingleton();
// FixedSubclassSingleton instance = new FixedSubclassSingleton();
}
#Test
public void testCreateExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FixedExtendableSingleton");
FixedExtendableSingleton singleton = FixedExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof FixedExtendableSingleton);
assertFalse(singleton instanceof FixedSubclassSingleton);
}
#Test
public void testCreateFixedSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FixedSubclassSingleton");
FixedExtendableSingleton singleton = FixedExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a FixedSubclassSingleton.
assertTrue(singleton instanceof FixedSubclassSingleton);
}
#AfterEach
protected void tearDown() {
FixedExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Clearer binding of subclass to singleton behavior.
Reduction of duplicate code.
Cons:
Only a fixed set of subclasses are defined. Adding a new subclass requires modifying the getInstance method.
Option 3. Determine which singleton to use from a dynamic set of classes.
This method attempts to remove the need to modify getInstance for every subclass. The idea is to include a registry (map) of names to singletons in the base class, and look up the correct one in getInstance.
In order to populate the registry with singletons, each singleton needs to be created beforehand. How is this done? According to GOF, we can assign a static variable to an instance of the object. When the class is loaded, the singleton is constructed, and the constructor adds the object to the registry. This is more complex, but it works (sort of).
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible;
import java.util.HashMap;
import java.util.Map;
//This singleton can be extended (subclassed)
public class FlexibleExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static FlexibleExtendableSingleton instance;
// This must appear before thisSingleton, because the constructor requires the registry.
protected static Map<String, FlexibleExtendableSingleton> registry = new HashMap<String, FlexibleExtendableSingleton>();
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static FlexibleExtendableSingleton thisSingleton = new FlexibleExtendableSingleton();
public static void activateClass() {
// Do nothing special.
}
private int sampleValue;
protected static void register(String name, FlexibleExtendableSingleton singletonClass) {
registry.put(name, singletonClass);
}
protected static FlexibleExtendableSingleton lookupFromRegistry(String name) {
return registry.get(name);
}
public static FlexibleExtendableSingleton getInstance() {
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
instance = lookupFromRegistry(singletonName);
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected FlexibleExtendableSingleton() {
// Protected insures construction cannot occur outside of class.
// Register the class when it is constructed by its static method.
// Subclasses will be able to use this method as well.
register(this.getClass().getSimpleName(), this);
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadExtendableSingleton;
public class FlexibleSubclassSingleton extends FlexibleExtendableSingleton {
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static FlexibleSubclassSingleton thisSingleton = new FlexibleSubclassSingleton();
private int sampleValue2;
public static void activateClass() {
// Do nothing special.
}
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected FlexibleSubclassSingleton() {
// The following line will also register the class.
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassflexible.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassflexible.FlexibleExtendableSingleton;
import study.design.patterns.creational.singleton.subclassflexible.FlexibleSubclassSingleton;
public class FlexibleExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// FlexibleExtendableSingleton instance = new FlexibleExtendableSingleton();
// FlexibleSubclassSingleton instance2 = new FlexibleSubclassSingleton();
}
#Test
public void testCreateFlexibleExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FlexibleExtendableSingleton");
FlexibleExtendableSingleton.activateClass();
FlexibleSubclassSingleton.activateClass();
FlexibleExtendableSingleton singleton = FlexibleExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof FlexibleExtendableSingleton);
assertFalse(singleton instanceof FlexibleSubclassSingleton);
}
#Test
public void testCreateFlexibleSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", "FlexibleSubclassSingleton");
FlexibleExtendableSingleton.activateClass();
FlexibleSubclassSingleton.activateClass();
FlexibleExtendableSingleton singleton = FlexibleExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a FlexibleSubclassSingleton.
assertTrue(singleton instanceof FlexibleSubclassSingleton);
}
#AfterEach
protected void tearDown() {
FlexibleExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Notice the method "activateClass" in each of the singletons. This method is empty and appears to do nothing. In reality, it is there to trigger loading the class for the first time. When called, the class is loaded, which creates the static singleton instance, which adds the entry to the registry. If the class is not loaded, the registry will not be populated and getInstance will return null for any class except for the base class, because calling getInstance will also trigger loading the base class.
Alternatively, instead of using "activateClass" methods, you could use a ClassLoader to load all of the singleton classes. You would still need to explicitly load every singleton class.
Pros:
getInstance does not have to be modified each time.
Cons:
Every subclass requires an empty activateClass method (or another way to load the class), which must be called prior to getInstance. Since each singleton class must be activated, we didn't gain much improvement from Option 2.
Option 4. Dynamically loading the singleton by name.
In Option 3 above, we had the problem of loading the singleton classes to populate a registry. Since the selection of the singleton is already being controlled by a system property, why not just load the singleton class to be used and set that as the instance?
Using reflection, we can load the class by name, locate the static singleton (the "thisSingleton" field), and assign it to the instance.
NOTE: Reflection enables a developer to bypass encapsulation, so should be used with caution. In this case, its use is limited to getInstance.
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload;
import java.lang.reflect.Field;
//This singleton can be extended (subclassed)
public class DynamicLoadExtendableSingleton {
// The instance - only one of these can exist in the system (currently not accounting for threads).
private static DynamicLoadExtendableSingleton instance;
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static DynamicLoadExtendableSingleton thisSingleton = new DynamicLoadExtendableSingleton();
private int sampleValue;
public static DynamicLoadExtendableSingleton getInstance() {
if (instance == null) {
String singletonName = System.getProperty("study.design.patterns.creational.singleton.classname");
ClassLoader loader = DynamicLoadExtendableSingleton.class.getClassLoader();
try {
Class<?> singletonClass = loader.loadClass(singletonName);
Field field = singletonClass.getDeclaredField("thisSingleton");
field.setAccessible(true);
instance = (DynamicLoadExtendableSingleton) field.get(null);
} catch (ClassNotFoundException e) {
// The class was not found.
// TODO: Add error handling code here.
} catch (NoSuchFieldException e) {
// The field does not exist - fix the singleton class to include thisSingleton field.
// TODO: Add error handling code here.
} catch (IllegalAccessException e) {
// Should not occur - we make the field accessible just for this purpose.
// TODO: Add error handling code here.
}
}
return instance;
}
public static void clearInstance() {
// This method wipes out the singleton.
// This is purely for testing purposes so getInstance can reconnect to a new singleton if needed.
instance = null;
}
public int getSampleValue() {
return sampleValue;
}
public void setSampleValue(int sampleValue) {
this.sampleValue = sampleValue;
}
protected DynamicLoadExtendableSingleton() {
// Protected insures construction cannot occur outside of class.
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload;
public class DynamicLoadSubclassSingleton extends DynamicLoadExtendableSingleton {
// This singleton - each class in the hierarchy needs one of these. It will trigger construction (and therefore, registration).
private static DynamicLoadSubclassSingleton thisSingleton = new DynamicLoadSubclassSingleton();
private int sampleValue2;
public int getSampleValue2() {
return sampleValue2;
}
public void setSampleValue2(int sampleValue2) {
this.sampleValue2 = sampleValue2;
}
// Must be defined to prevent creation of a public default constructor.
protected DynamicLoadSubclassSingleton() {
super();
}
}
/////////////////////////////////////////////////////////////////////////////
package study.design.patterns.creational.singleton.subclassdynamicload.test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadExtendableSingleton;
import study.design.patterns.creational.singleton.subclassdynamicload.DynamicLoadSubclassSingleton;
public class DynamicLoadExtendableSingletonTest {
#Test
public void testIllegalCreation() {
// The following lines will not compile because the constructor is not visible.
// DynamicLoadExtendableSingleton instance = new DynamicLoadExtendableSingleton();
// DynamicLoadSubclassSingleton instance2 = new DynamicLoadSubclassSingleton();
}
#Test
public void testCreateDynamicLoadExtendableSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", DynamicLoadExtendableSingleton.class.getName());
DynamicLoadExtendableSingleton singleton = DynamicLoadExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is an ExtendableSingleton, but not a FixedSubclassSingleton.
assertTrue(singleton instanceof DynamicLoadExtendableSingleton);
assertFalse(singleton instanceof DynamicLoadSubclassSingleton);
}
#Test
public void testCreateDynamicLoadSubclassSingleton() {
System.setProperty("study.design.patterns.creational.singleton.classname", DynamicLoadSubclassSingleton.class.getName());
DynamicLoadExtendableSingleton singleton = DynamicLoadExtendableSingleton.getInstance();
assertNotNull(singleton);
// Check that the singleton is a DynamicLoadSubclassSingleton.
assertTrue(singleton instanceof DynamicLoadSubclassSingleton);
}
#AfterEach
protected void tearDown() {
DynamicLoadExtendableSingleton.clearInstance();
}
}
/////////////////////////////////////////////////////////////////////////////
Pros:
Subclasses do not require a method to activate the class. The only code required is a "thisSingleton" field.
The getInstance method does not require modification for each new subclass.
Cons:
Reflection can be slower, but since it's only used in one place and only when the singleton is assigned, the risk is minimal.
It's possible to get an error if the class name is incorrect. Again, this is a minimal risk.
In summary, while subclassing a singleton may not be common, it is addressed in the GOF book as feasible. There are a few ways to support subclassing singletons, each with benefits and drawbacks. Some of the methods listed above come directly from the book. The method of using reflection was my addition.
Are you looking to provide some inheritable behavior to a number of singleton's? If so, perhaps you could move that code into an abstract class.
As SLaks pointed out, extending a singleton would no longer make it a singleton pattern.

Categories