2017-06-20 6 views
0

Zu wissen, dass Storage ist eine Schnittstelle und StorageXX sind ihre Implementierungen, ich möchte wissen, ob es möglich ist, den folgenden Code zu ersetzen ...Schalter ersetzen durch dynamische Konstruktor

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(); 
} 

... von einem „dynamischen Konstruktor "des Speichers, der einen String-Parameter (den storageType) genommen hat, gibt die jeweils gewünschte Instanz zurück ...

Es spielt keine Rolle, ob Storage eine abstrakte Klasse sein soll.

Ich würde lieber lieber eine switch-Anweisung vermeiden, wenn möglich.

+1

Mögliches Duplikat von [So erhalten Sie ein Klassenobjekt aus dem Klassennamen in Java] (https://stackoverflow.com/questions/1438420/how-to-get-a-class-object-from-the-class -name-in-java) – UnholySheep

+0

Wenn Sie "StorageDB" in "StorageDb" umbenannt haben, können Sie den Namen dynamisch erstellen und Reflektion verwenden. – Andreas

+0

Würde [diese Antwort] (https://stackoverflow.com/a/29220300/6893866) aus einer anderen Frage Ihre Bedürfnisse gut genug? (erfordert Java 8) – Tezra

Antwort

1

Sie Factory-Muster für das verwenden können.

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(); 
    } 
} 

und eine Speicherliste zu erstellen:

Storage storage = StorageFactory.getStorage("list"); 
+0

Sie haben gerade eine 'switch' Anweisung mit mehreren' if' Anweisungen ersetzt. Wie ist das anders? – Andreas

+0

Nun, ich verstehe, dass er etwas gegen die 'switch' nicht' if' Aussage hat und ich präsentiere ihm ein Muster. Ich glaube nicht, dass ich dafür eine Abstimmung verdiene, aber es ist in Ordnung. – Dherik

+0

Stimmen Sie mit @Dherik überein. Du verdienst keine Donwvote, wie ich gesagt habe: "Weiche wenn möglich aus". Das ist genau das, was ich brauche danke – Arcones

0

Sie könnten eine Karte von storage Klasse erstellen

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

und dann Instanziierung über Class verwenden:

Class<? extends Storage> clazz = map.get(storageType); 
if (clazz == null) { 
    throw new UnsupportedStorageTypeException(); 
} 
Storage storage = clazz.newInstance(); 
+0

Wenn Sie Java 8 verwenden, können Sie die Konstruktoren einfach in der Map speichern und die Reflektion überspringen. Siehe hierzu [Antwort] (https://stackoverflow.com/a/29220300/6893866). – Tezra

2

Factory Pattern etwas, das Sie in aussehen sollte. Es macht genau das, was du willst.

+0

Danke !!! Ich schaue mir das Tutorial an. Ich habe Dherik als die richtige Antwort markiert, da er schneller war, aber deine ist genauso nützlich – Arcones