Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement an abstract singleton class in Java?

Here is my sample abstract singleton class:

public abstract class A {     protected static A instance;     public static A getInstance() {         return instance;     }     //...rest of my abstract methods... } 

And here is the concrete implementation:

public class B extends A {     private B() { }     static {         instance = new B();     }     //...implementations of my abstract methods... } 

Unfortunately I can't get the static code in class B to execute, so the instance variable never gets set. I have tried this:

Class c = B.class; A.getInstance() - returns null; 

and this

ClassLoader.getSystemClassLoader().loadClass("B"); A.getInstance() - return null; 

Running both these in the eclipse debugger the static code never gets executed. The only way I could find to get the static code executed is to change the accessibility on B's constructor to public, and to call it.

I'm using sun-java6-jre on Ubuntu 32bit to run these tests.

like image 764
Simon Avatar asked Mar 17 '10 00:03

Simon


People also ask

Can a abstract class be Singleton in Java?

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.

What are some ways to implement a Singleton in Java?

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.

What is the best way to implement a singleton class?

Eager initialization: In eager initialization, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a Singleton class. By making the constructor as private you are not allowing other class to create a new instance of the class you want to create the Singleton.

What is Singleton in Java and how do we implement it?

In Java, Singleton is a design pattern that ensures that a class can only have one object. To create a singleton class, a class must implement the following properties: Create a private constructor of the class to restrict object creation outside of the class.


2 Answers

Abstract Singleton? Doesn't sound viable to me. 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.

like image 117
BalusC Avatar answered Sep 30 '22 23:09

BalusC


You are trying to get an abstract class play two very different roles:

  • the abstract factory role for a (singleton) service that can have multiple substitutable implementations,
  • the service interface role,

and on top of that you also want the service to be singleton and enforce 'singletoness' on the entire family of classes, for some reason you aren't considering caching the service instances.

Somebody (I would) will say it smells very bad, for multiple reasons it violates separation of concerns, singletons make unit testing impossible", etc.

Somebody else will say it's ok-ish, it doesn't need a lot of different infrastructure and has kind of fluent-ish interface that you see in some very common third party (legacy) Java API.

The bad part is demanding the children to select what implementation should the parent factory method return. That responsibility should be pushed up and centralised into the abstract superclass. Otherwise you are mixing together patterns that are used in very different contexts, Abstract Factory (parent decide what family of classes clients are going to get) and Factory Method (children factories select what the clients will get).

Factory Method is also not practically possible because you can't override static methods, nor constructors.

There are some (ugly) ways to achieve your objective though:

public abstract class A{     public static A getInstance(...){       if (...)          return B.getInstance();       return C.getInstance();     }      public abstract void doSomething();      public abstract void doSomethingElse();  }  public class B extends A{     private static B instance=new B();      private B(){     }      public static B getInstance(){         return instance;     }      public void doSomething(){         ...     }     ... }  //do similarly for class C 

The parent could also use reflection, cache instances, etc.

A more test and extension friendly solution is simply standard separation of concerns. The children aren't going to be singleton anymore per se, but you package them into some internal package that you will document as "private" and a public abstract parent in an external package will handle caching or pooling of children instances, enforcing whatever instantiation policy is required on these classes.

like image 25
Benedetto Fiorelli Avatar answered Oct 01 '22 01:10

Benedetto Fiorelli