views:

611

answers:

5

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 get**NewModel().**.

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 .

A: 

Can you refactor the interface to be an abstract class? This will allow you to force a particular factory method down to all implementing classes.

shambleh
Tried that .Abstract class won't work
Duleb
Polymorphism won't work in case of static method. See if u have a static method in abstract class and u override it in subclass, then if you try to access that method the original one would be called not the subclass's method.
Duleb
Ahhh, of course, sorry about that.
shambleh
+3  A: 
  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.

# this line is to keep S.O.'s markdown from assuming the code below is part of the list above

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(); }
}
KitsuneYMG
Factory is fine.But i am curious if the same functionality can be achieved without Factory.
Duleb
I am working on eclipse. The Model interface is the contract for Extension point.The Implementation of Model is the Extension. So i need to expose the myxmlModel.If i expose some Factory class then since it donot implement Model, the Contract will Fail.
Duleb
A: 

I used to ask myself the same question. And I proposed the same answer ;-)

Now I normally drop the "forcing" behavior, I rely on documentation. I found no case where the Singleton aspect was so compelling that it needed to be enforced by all means. It is just a "best-practice" for the project.

I usually use Spring to instanciate such an object, and it is the Spring configuration that makes it a Singleton. Safe, and so easy ... plus additionnal Spring advantages (such as Proxying, substituing a different object once to make some tests etc...)

KLE
A: 

This is more an answer to your comment/clarification to kts's answer. Is it so, that the real problem is not using the Singleton pattern but instead defining an eclipse (equinox) extension point schema that allows contributing a singleton?

I think, this can't be done, because everytime you call IConfigurationElement.createExecutableExtension you create a new instance. This is quite incompatible with your singleton requirement. And therefore you need the public default constructor so that everybody can create instances.

Unless you can change the extension point definition so that plugins contribute a ModelFactory rather than a model, like

public interface ModelFactory {

  public Model getModelInstance();

}

So the extension user will instantiate a ModelFactory and use it to obtain the singleton.

If I guessed wrong, leave a comment and I delete the answer ;)

Andreas_D
Yes you are right.But if i expose the factory Class then the Contract (i.e to implement the Model interface) will Fail.There are many other methods in IConfigurationElement which we can use to get more info about the extension ,maybe get the class name and call a static method on it to get a Object. But then again we return to square one.We cannot have static declaration in Model interface.
Duleb
Not exactly - the contract is just moved to the ModelFactory class. Now you'll have two contracts: The Factory (contribution through extension point) and the Model (Factory has to return a Model implementation)
Andreas_D
A: 

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.

Vitaly
I think Reflection Will Work.
Duleb