8

I have common code (multiple class that I call controllers) that needs to be shared by multiple packages in the project. I was thinking of creating a factory, that returns these controllers. So, the factory would have a hashmap, that can return the controller asked for or create a new one if not created. The controllers have common code and since I don't need to create multiple instances of these controller, I think they should be singletons.

Does this seem like a good approach?

12rad
  • 829
  • 2
  • 13
  • 28

2 Answers2

16

I think what you need is a Multiton pattern.

The multiton pattern is a design pattern similar to the singleton, which allows only one instance of a class to be created. The multiton pattern expands on the singleton concept to manage a map of named instances as key-value pairs. Rather than have a single instance per application (e.g. the java.lang.Runtime object in the Java programming language) the multiton pattern instead ensures a single instance per key.

public class FooMultiton {
    private static final Map<Object, FooMultiton> instances = new HashMap<Object, FooMultiton>();

    private FooMultiton() {
        // no explicit implementation
    }

    public static synchronized FooMultiton getInstance(Object key) {

        // Our "per key" singleton
        FooMultiton instance = instances.get(key);

        if (instance == null) {
            // Lazily create instance
            instance = new FooMultiton();

            // Add it to map   
            instances.put(key, instance);
        }

        return instance;
    }

    // other fields and methods ...
}

The controllers have common code and since I don't need to create multiple instances of these controller, I think they should be singletons.

You need single instance does not necessarily mean that you need a Singleton Pattern. You can have a single instance and pass that on subsequent calls to that. Don't necessarily enforce singletonness using private constructor.

Also read Evil Singletons for more on down points of Singletons. After reading that if you still feel you need Singleton then go with it.

Community
  • 1
  • 1
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • This pattern is very similar to flyweight pattern, but in flyweight you have to ensure that the flyweights don't have internal state for proper use, the same as here.. Also it's not recommended to use an `Object` as a key in a hash "key-value collection" .! – nachokk Dec 09 '13 at 13:33
  • @nachokk The program is not necessarily for great performance ;) Just to get the idea out. BTW it is from Wikipedia. But a good point though. – Narendra Pathai Dec 09 '13 at 14:34
  • Not for performance, "All hash-based collections assume that an object’s hash value does not change while it is in use as a key in the collection. If a key’s hash code were to change while it was in a collection, some unpredictable and confusing consequences could follow". – nachokk Dec 09 '13 at 15:00
2

Yes it does. The Singleton design pattern suffer for several problems, one of which is that Singletons cannot be extended.

However, if you retrieve these controllers via a ControllerFactory.createControllerX() instead of ControllerX.getInstace(), you will be able to extended ControllerX in future and all its client will not be aware of using an extended version. Which is a really good thing

Raffaele Rossi
  • 1,079
  • 5
  • 11