it-swarm.com.de

If-else-Anweisung durch pattern ersetzen

Ich habe eine if-else-Aussage, die in naher Zukunft wachsen könnte. 

    public void decide(String someCondition){

        if(someCondition.equals("conditionOne")){
            //
            someMethod("someParameter");

        }else if(someCondition.equals("conditionTwo")){

           //
           someMethod("anotherParameter");

        }
        .
        .
        else{

            someMethod("elseParameter");

        }
}

Da dies schon unordentlich aussieht, wäre es meiner Meinung nach besser, wenn ich hier Designmuster anwenden kann. Ich habe mir das Strategiemuster angesehen, aber ich bin nicht sicher, ob dies die Bedingung reduzieren würde. Irgendwelche Vorschläge?

29
cosmos

Dies ist ein klassischer Replace Condition Dispatcher mit Command im Buch Refactoring in Patterns.

enter image description here

Grundsätzlich erstellen Sie ein Command-Objekt für jeden der Codeblöcke in Ihrer alten if/else-Gruppe und erstellen dann eine Map dieser Befehle, bei denen die Schlüssel Ihre Bedingungszeichenfolgen sind

interface Handler{
    void handle( myObject o);
}


 Map<String, Handler> commandMap = new HashMap<>();
 //feel free to factor these out to their own class or
 //if using Java 8 use the new Lambda syntax
 commandMap.put("conditionOne", new Handler(){
         void handle(MyObject o){
                //get desired parameters from MyObject and do stuff
          }
 });
 ...

Anstelle Ihres if/else-Codes gilt dann:

 commandMap.get(someCondition).handle(this);

Wenn Sie später neue Befehle hinzufügen müssen, fügen Sie einfach den Hash hinzu.

Wenn Sie einen Standardfall behandeln möchten, können Sie das Null Object-Muster verwenden, um den Fall zu behandeln, bei dem eine Bedingung nicht in der Map enthalten ist.

 Handler defaultHandler = ...

if(commandMap.containsKey(someCondition)){
    commandMap.get(someCondition).handle(this);
}else{
    defaultHandler.handle(this);
}
34
dkatzel

Die allgemeine Empfehlung von Martin Fowler lautet: Bedingte durch Polymorphismus ersetzen .

In Bezug auf Entwurfsmuster wäre dies häufig das Strategiemuster Ersetzen der bedingten Logik durch Strategie .

Wenn Sie eine kleine, endliche Menge von Bedingungen haben, empfehle ich die Verwendung eines enum, um das Strategiemuster zu implementieren. 

public enum SomeCondition{
   CONDITION_ONE{

       public void someMethod(MyClass myClass){
              //...
       }
   },

   CONDITION_TWO{

       public void someMethod(MyClass myClass){
       }

   }

   public abstract void someMethod(MyClass myClass);

}

public class MyClass{
//...
    public void decide(SomeCondition someCondition){
        someCondition.someMethod(this);
    }

}

Wenn es sich wirklich nur um einen Parameter handelt, den Sie auswählen möchten, können Sie stattdessen die Aufzählung folgendermaßen definieren:

public enum SomeCondition{
   CONDITION_ONE("parameterOne"),

   CONDITION_TWO("parameterTwo");

   private SomeCondition(String parameter){
       this.parameter = parameter;
   }

   public String getParameter(){
       return parameter;
   }

}


public class MyClass{
//...
    public void decide(SomeCondition someCondition){
        someMethod(someCondition.getParameter());
    }

}
14
Puce

Ich denke, Sie müssen es bereits bedacht haben, aber wenn Sie JDK 7 oder höher verwenden, können Sie Strings einschalten. Auf diese Weise kann Ihr Code sauberer aussehen als eine Reihe von if-else-Anweisungen.

0
mehmetakcay