Sostituire if else statement with pattern

Ho una dichiarazione if else che potrebbe crescere nel prossimo futuro.

public void decide(String someCondition){ if(someCondition.equals("conditionOne")){ // someMethod("someParameter"); }else if(someCondition.equals("conditionTwo")){ // someMethod("anotherParameter"); } . . else{ someMethod("elseParameter"); } } 

Dal momento che questo sembra già disordinato, penso che sarebbe meglio se potessi applicare qualsiasi schema di design qui. Ho esaminato il modello di strategia, ma non sono sicuro che questo ridurrà le altre condizioni qui. Eventuali suggerimenti?

Questo è un classico dispatcher di sostituzione delle condizioni con comando nel libro Refactoring to Patterns.

inserisci la descrizione dell'immagine qui

Fondamentalmente si crea un object Command per ognuno dei blocchi di codice nel vecchio gruppo if / else e quindi si crea una mappa di quei comandi in cui le chiavi sono le proprie condizioni.

 interface Handler{ void handle( myObject o); } Map 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 } }); ... 

Quindi invece del tuo codice if / else è invece:

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

Ora se hai bisogno di aggiungere nuovi comandi, aggiungi semplicemente l’hash.

Se si desidera gestire un caso predefinito, è ansible utilizzare il modello Null Object per gestire il caso in cui una condizione non è presente nella Mappa.

  Handler defaultHandler = ... if(commandMap.containsKey(someCondition)){ commandMap.get(someCondition).handle(this); }else{ defaultHandler.handle(this); } 

La raccomandazione generale di Martin Fowler è di sostituire il condizionale con il polimorfismo .

In termini di schemi di progettazione, questo è spesso il modello strategico Sostituisci la logica condizionale con la strategia .

Se si dispone di un insieme limitato di condizioni, si consiglia di utilizzare un enum per implementare il modello di strategia (fornire un metodo astratto nell’enumerazione e sovrascriverlo per ciascuna costante).

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

Se è davvero solo un parametro che vuoi selezionare, allora potresti definire l’enume come questo:

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

Immagino che tu debba averlo già preso in considerazione, ma se stai usando JDK 7 o superiore, puoi triggersre le stringhe. In questo modo il tuo codice può sembrare più pulito di una serie di istruzioni if-else.