0

Knowing that Storage is an interface and StorageXX are its implementations, I want to know if it is possible to replace the following code...

Storage storage;
switch (storageType) {
    case "list":
        storage = new StorageList();
        break;
    case "map":
        storage = new StorageMap();
        break;
    case "db":
        storage = new StorageDB();
        break;
    default:
        throw new UnsupportedStorageTypeException();
}

... by a "dynamic constructor" of Storage that taken a String parameter (the storageType) , returns the instance I want in each case...

It doesn't matter if Storage should be an abstract class.

I would rather prefer to avoid any switch statement if possible.

Arcones
  • 3,954
  • 4
  • 26
  • 46
  • 1
    Possible duplicate of [How to get a Class Object from the Class Name in Java](https://stackoverflow.com/questions/1438420/how-to-get-a-class-object-from-the-class-name-in-java) – UnholySheep Jun 20 '17 at 19:10
  • If you renamed `StorageDB` to `StorageDb`, you could build the name dynamically, and use reflection. – Andreas Jun 20 '17 at 19:26
  • Would [this answer](https://stackoverflow.com/a/29220300/6893866) from another question fit your needs well enough? (requires Java 8) – Tezra Jun 20 '17 at 19:30

3 Answers3

2

Factory Pattern is something that you should look into. It does exactly what you want.

Inxsible
  • 700
  • 5
  • 27
  • Thank you!!! I am having a look at the tutorial. I have marked as the correct answer Dherik's as he was faster but yours it's equally useful – Arcones Jun 20 '17 at 19:38
1

You can use Factory Pattern for that.

class StorageFactory
{
  public static Storage getStorage(String type)
  {
    if ( type.equals("list") )
      return new StorageList();
    else if ( type.equals("map") )
      return new StorageMap();
    else if ( type.equals("db") )
      return new StorageDb();

    throw new IllegalArgumentException();
  }
}

And to create a storage list:

Storage storage = StorageFactory.getStorage("list");
Dherik
  • 17,757
  • 11
  • 115
  • 164
  • You just replaced a `switch` statement with multiple `if` statements. How is that any different? – Andreas Jun 20 '17 at 19:24
  • Well, I understand that he has something against the `switch` not `if` statement and I present to him a pattern. I don't think I deserve a down vote for that, but it's ok. – Dherik Jun 20 '17 at 19:31
  • Agree with @Dherik. You don't deserve a donwvote as I said "avoid switch if possible". This is just what I need thank you – Arcones Jun 20 '17 at 19:36
0

You could create a map from storageType to class

Map<String, Class<? extends Storage>> map = new HashMap<>();
map.put("list", StorageList.class);
map.put("map", StorageMap.class);
map.put("db", StorageDB.class);

and then use instantiation via Class:

Class<? extends Storage> clazz = map.get(storageType);
if (clazz == null) {
    throw new UnsupportedStorageTypeException();
}
Storage storage = clazz.newInstance();
Roman Puchkovskiy
  • 11,415
  • 5
  • 36
  • 72
  • If using Java 8, you could just store the constructors in the map and skip the reflection. See this [answer](https://stackoverflow.com/a/29220300/6893866). – Tezra Jun 20 '17 at 19:29