2016-12-09 12 views
1

switch文をポリモフィズムで置き換える方法については、hereのように説明しています。私の場合はJavaリファクタリング多相対応スイッチ/ if文

しかし、私は2つの列挙型を持っている:

public enum EleType { 
    INTEGER, 
    CHARACTER 
} 

public enum SorterType { 
    BUBBLE, 
    INSERTION 
} 

およびスイッチ/私はリファクタリングしたい場合は、以下の構造を有する:

if (eleType == EleType.INTEGER) { 
    switch (sorterType) { 
     case BUBBLE: 
      composition = new SorterComposition<Integer>(new BubbleSort<Integer>(), randomList); 
      break; 
     case INSERTION: 
      composition = new SorterComposition<Integer>(new InsertionSort<Integer>(), randomList); 
      break; 
    } 
} else if (eleType == EleType.CHARACTER) { 
    switch (sorterType) { 
     case BUBBLE: 
      composition = new SorterComposition<Character>(new BubbleSort<Character>(), randomList); 
      break; 
     case INSERTION: 
      composition = new SorterComposition<Character>(new InsertionSort<Character>(), randomList); 
      break; 
    } 
} 

ので、両方の列挙型が一緒に表示され、どちらもSorterComposition部分に影響します。この構造体をどのようにリファクタリングするかはわかりません。また、 "Integer"/"Character"ジェネリック型を、それぞれ、条件文を使わずにEleType.INTEGERまたはEleType.CHARACTERから取得する方法がわかりません。

答えて

1

このようなコードを実装することを意味しますか?

public static <T> SorterComposition<T> createComposition(SorterType type, <Type of randomList>) { 
    switch (type) { 
     case BUBBLE: 
      return new SorterComposition<T>(new BubbleSort<T>(), randomList); 
     case INSERTION: 
      return new SorterComposition<T>(new InsertionSort<T>(), randomList); 
     default: 
      throw <Exception> 
    } 
} 

それとも、あなたはEleTypeクラスを少し変更することができます。

public enum EleType { 
    INTEGER(Integer.class), CHARACTER(Character.class); 
    private EleType(Class cl) { this.classType = cl; } 
    public Class getClassType() { return classType; } 
    private final Class classType; 
} 

上記のcreateCompositionの代わりにこのコードを使用してください。

public static <T> SorterComposition<T> createComposition(Class<T> eleType, SorterType type, <Type of randomList>) { 
    switch (type) { 
     case BUBBLE: 
      return new SorterComposition<T>(new BubbleSort<T>(), randomList); 
     case INSERTION: 
      return new SorterComposition<T>(new InsertionSort<T>(), randomList); 
     default: 
      throw <Exception> 
    } 
} 

、あなたがそれを使用する場合、composition = createComposition(eleType.getClassType(), sorterType, randomList);


は、多分あなたはSorterTypeSupplierフィールドを追加で使用することができ、穏やかな方法でSorterTypeswitchを回避するために使用します。

public enum SorterType { 
    BUBBLE(() -> new BubbleSort()), 
    INSERTION(() -> new InsertionSort()); 

    private SorterType(Supplier<Sort> supplier) { 
     this.supplier = supplier; 
    } 

    public Sort getSort() { 
     return supplier.get(); 
    } 

    private final Supplier<Sort> supplier; 
} 
+0

私の第二の問題(EleTypeからInteger.classへのマッピングなど)を解決しているようです。しかし、私はまだ何とかswitch文を取り除きたい。 – user1583209

+0

アップデートのコードはどうですか? 'EleType'にフィールドを追加し、' createComposition'を呼び出すときに 'eleType.getClassType()'を渡します。 – EmOwen

+0

これはどのように 'SorterType'のスイッチを取り除きますか? – user1583209

0

ダブルディスパッチを使用できます。私は以下のスケルトン実装を提供しました。 しかし、いくつか検討してくださいdouble dispatch a code smell.あなたのEleTypeは私に疑わしいと思われる。この例では、ジェネリック型宣言に使用しています。 EleTypeを変更

public enum EleType { 
    INTEGER { 
     SorterComposition getSorter(SorterType s) { 
      return s.getIntegerSorter(); 
     } 
    }, 
    CHARACTER{ 
     SorterComposition getSorter(SorterType s) { 
      return s.getChracterSorter(); 
     } 

    }; 

    abstract SorterComposition getSorter(SorterType s); 
}; 

public enum SorterType { 
    BUBBLE { 
     SorterComposition getIntegerSorter() {return new BubbleSort<Integer>();} 
     SorterComposition getChracterSorter() {return new BubbleSort<Character>();} 
    }, 
    INSERTION{ 
     SorterComposition getIntegerSorter() {return new InsertionSort<Integer>();} 
     SorterComposition getChracterSorter() {return new InsertionSort<Character>();} 
    }; 

    abstract SorterComposition getIntegerSorter(); 
    abstract SorterComposition getChracterSorter(); 

}; 
関連する問題