I have some classes that are used as Singletons. They share some basic functionality and extend the same ancestor from a library which in turn isn't normally used as a Singleton.
If I put the common functionality in a base class that inherits from the common ancestor, I get a class which makes no sense to instantiate, so I made it abstract. Also, because the classes are all used as Singletons, they should all have an init() and a getInstance() method, which are both static. All the constructors are of course non-public.
Now, since static
is an illegal modifier for abstract methods, the following doesn't work, although this would be exactly what I want:
class Base extends LibraryClass {
protected Base() {
// ... constructor
}
// ... common methods
// ILLEGAL!
public static abstract void init();
public static abstract <T extends Base>T getInstance();
}
class A extends Base {
private static A _INSTANCE;
private A() {
super();
}
public static void init() {
_INSTANCE = new A();
}
public static A getInstance() {
return _INSTANCE;
}
}
I could just leave out the illegal lines in the base class and be done with it. But how do I express that every child of Base must have these methods?
Most other languages simply do not allow defining abstract singleton class methods (for example, static methods in TypeScript, C++, Java, C#, and more are not allowed to be abstract).
The Singleton pattern requires a private constructor and this already makes subclassing impossible. You'll need to rethink your design. The Abstract Factory pattern may be more suitable for the particular purpose. The purpose of the private constructor in the Singleton is to prevent anyone else instantiating it.
You cannot inherit or instantiate a static class. Unlike static classes, Singleton classes can be inherited, can have base class, can be serialized and can implement interfaces. You can implement Dispose method in your Singleton class. So, static classes are much less flexible compared to Singleton classes.
The most popular approach is to implement a Singleton by creating a regular class and making sure it has: A private constructor. A static field containing its only instance. A static factory method for obtaining the instance.
This is not possible in Java. Existence of static
methods can't be enforced; neither by abstract
nor by using an interface
.
My solution was to use IoC in a way: I created a factory class for singletons. It would save the singletons in a map. The key would be the class. This way, I could say:
A singleton = Factory.create (A.class);
The major advantage of this design: I can create a Factory.replace()
method where test cases can override the singletons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With