レガシーコードをリファクタリングしようとしていますが、この場合、実行するコマンドを決定するスイッチケースの巨大なブロックがあります
switch(operation)
case addition : return add(int a, String b, String c);
case multiply : return multiply(int a, int b);
case substract : return substract(int a, int b);
アプローチ1:ポリモーフィズムの使用
public interface Operation {
void performOperation(int a, int b);
}
次に、使用可能な実装をマップに入力します。
Map<Key, Operation> actions = new HashMap<>();
actions.add(addition, new addOperation());
actions.add(multiply, new multiplyOperation());
actions.add(substract, new substractOperation());
その後、操作を実行する必要があるときにマップを参照できます。
このアプローチで私が抱えている問題は、多数のクラス/匿名クラスを作成する必要があることです
アプローチ2:Enumの使用
public enum MyKeyEnum {
ADDITION {
public void performOperation(int a, int b) {
// Perform addition
}
},
MULTIPLY {
public void performOperation(int a, int b) {
// Perform Multiplication
}
};
public abstract void performOperation(int counter, String dataMain, String dataSub);
}
このアプローチは実際には2つのうちの方が優れていますが、Java 8で別の例を見て、このようなものを使用したいと思います
これらはすべてパターンに従っているので、機能インターフェースとマップを使用しようとしました
final static Map<String, Supplier<IAction>> map = new HashMap<>();
static {
map.put("add", Addition::new);
map.put("multiply", Multiply::new);
}
public static void main(String[] args) throws Exception {
Supplier<IAction> action = map.get("add");
System.out.println(action.get().performAction(10,10));
action = map.get("multiply");
System.out.println(action.get().performAction(10,10));
}
しかし、これにも最初のアプローチの欠点があるため、Enum実装を使用したようにラムダを使用できるかどうかを確認したいと思いました。Java8で提供されている部分的な関数実装があり、これを使用したいと思いました。
BiFunction<Integer, Integer, Integer> minus = (x, y) -> x - y;
Function<Integer, Integer> subtractor = partial(minus, 10);
System.out.println(subtractor.apply(4)); // 6
BiFunctionは2つのパラメーターしか受け入れないため、次のようなTrifuctionを作成しました。
@FunctionalInterface
interface TriFunction<T, U, V, R> {
R apply(T a, U b, V c);
}
public static <T, U, V, R> Function<V, R> partial(TriFunction<T, U, V, R> f, T x, U y) {
return (z) -> f.apply(x, y, z);
}
これはある程度問題を解決しますが、これをマップに追加して動的に値を渡す方法を理解できません
Map<String, TriFunction<String, Integer, Integer, Operation>> map
= new HashMap<>();
あなたはすでにそこにいます。インターフェースと同じシグネチャを持つメソッドがある場合は、次のように操作リポジトリに渡すこともできます。
Map<String, IntBinaryOperator> operations = new HashMap<>();
operations.put("add", Integer::sum);
operations.put("subtract", (a, b) -> a - b);
operations.put("multiply", (a, b) -> a * b);
//...
System.out.println(operations.get("multiply").applyAsInt(10, 20));
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加