4

I am have a number of classes which implement same interface. The objects for all those classes have to be instantiated in a main class. I am trying to do it in a manner with which this thing could be done in an elegant manner (I thought through enum). Example code :-

public interface Intr {
//some methods
}

public class C1 implements Intr {
// some implementations
}

public class C2 implements Intr {
// some implementations
}

...

public class Ck implements Intr {
// some implementations
}


public class MainClass {

enum ModulesEnum {
//Some code here to return objects of C1 to Ck
 FIRST {return new C1()},
 SECOND {return new C2()},
 ...
 KTH  {return new Ck()};
}

}

Now in the above example for some elegant way with which I can get instances of new objects of Class C1 to Ck. Or any other better mechanism instead of enum will also be appreciated.

Siddharth
  • 2,046
  • 5
  • 26
  • 41
  • not clear, what do you want to achieve? – Braj Jul 25 '14 at 05:56
  • 1
    Use a factory instead. – Makoto Jul 25 '14 at 05:56
  • The factory pattern is your best choice there. Something like this http://alvinalexander.com/java/java-factory-pattern-example – elbuild Jul 25 '14 at 05:57
  • I saw a somewhat similar but not exactly same kind of stuff at http://stackoverflow.com/questions/9825708/initialize-a-new-object-from-class-in-enum . So I thought that it could be achieved through enum. – Siddharth Jul 25 '14 at 05:58
  • it seems like you need some sort of Factory pattern here. Depending on `how` you want to create those objects, you may like to use Factory, Factory Method or Abstract Factory pattern. – Pat Jul 25 '14 at 06:37

3 Answers3

9
enum ModulesEnum {

  FIRST(new C1()), SECOND(new C2()); // and so on

  private ModulesEnum(Intr intr) { this.obj = intr; }
  private Intr obj;

  public Intr getObj() { return obj; }

}

Hope that helps. The trick is to add an implementation to every enum. If you want to access the object, use the getter.

ModulesEnum.FIRST.getObj();

If your Intr and its implementations are package protected, you can make ModulesEnum public to expose the implementations. This way you can have only one instance per implementation, making them singleton without using the pattern explicitly.

You can of course use a Factory too if you intend to have multiple instances for every implementation.

Silviu Burcea
  • 5,103
  • 1
  • 29
  • 43
1

What you need is the Factory pattern. Whether or not you need want to use the Enum class as the factory itself is another issue. You could do something like this:

public enum Module {
    FIRST, SECOND, ..., KTH
}

public class ModuleFactory {
    public Intr createModule(Module module) {
        switch (module) {
            case FIRST:
                return new C1();
            case SECOND:
                return new C2();
            ...
            case KTH:
                return new Ck();
            ...
        }
    }
}

Without knowing how you plan on using these objects, I can't really say which is the more appropriate approach.

aberrant80
  • 12,815
  • 8
  • 45
  • 68
  • I am building a test case generator. It has various modules like random number generator, random string generator, random date generator, etc. In future more modules will be added to it. These all are managed through one main class. Now my point is whenever I add a new module to the software, minimum amount of code should be changed in the main class. For this purpose I need this. – Siddharth Jul 25 '14 at 06:13
  • If you're looking for minimal changes, you might want to consider a listener/observer approach. You would have a "ModuleRegistry", then for each new class that needs to be added to it, simply locate the "ModuleRegistry" (injection, static method, constructor, etc.) and each class would register itself. "ModuleRegistry" would maintain a map. – aberrant80 Jul 30 '14 at 15:03
0

Use a static factory.

public IntrFactory {

    static Intr first() {
        return new C1();
    }

    static Intr second() {
        return new C2();
    }

    ...
}
Gabriel Negut
  • 13,860
  • 4
  • 38
  • 45