Force Singleton Pattern on a Class implementing an Interface

10,096

Solution 1

  1. Make a factory that returns instances of your interface, Model.
  2. Make all concrete implementations of the model package-private classes in the same package as your factory.
  3. If your model is to be a singleton, and you are using java 5+, use enum instead of traditional singleton, as it is safer.
public enum MyXMLModel{  
INSTANCE();  
//rest of class  
};

EDIT: Another possibility is to create delegate classes that do all the work and then use an enum to provide all of the Model Options.

for instance:

class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}

class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}

public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());

private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }

public void foo() { delegate.foo(); }
}

Solution 2

You can use reflection. Something like this:

public interface Model {
  class Singleton {
    public static Model instance(Class<? extends Model> modelClass) {
      try {
        return (Model)modelClass.getField("instance").get(null);
     } catch (blah-blah) {
       blah-blah
     }
  }
}

public class XmlModel implements Model {
  private static final Model instance = new XmlModel();

  private XmlModel() {
  }
}

usage:

Model.Singleton.instance(XmlModel.class)

Actually, I don't like this code much :). First, it uses reflection - very slow, second - there are possibilities of runtime errors in case of wrong definitions of classes.

Share:
10,096
Duleb
Author by

Duleb

Updated on June 04, 2022

Comments

  • Duleb
    Duleb almost 2 years

    I better explain the question with an example. I have an Interface Model which can be used to access data. There can be different implementations of Model which can represent the data in various format say XMl , txt format etc. Model is not concerned with the formats. Lets say one such implementation is myxmlModel.

    Now i want to force myxmlModel and every other implementation of Model to follow Singleton Pattern.The usual way is to make myxmlModels constructor private and provide a static factory method to return an instance of myModel class.But the problem is interface cannot have static method definitions and a result i cannot enforce a particular Factory method definition on all implementation of Model. So one implementation may end with providing getObject() and other may have getNewModel()..

    One work around is to allow package access to myxmlModel's constructor and create a Factory class which creates the myxmlModel object and cache it for further use.

    I was wondering if there is a better way to achieve the same functionality .