Strategy
個人的重要度と感想
★★★★★
処理や計算ロジックを外部に委託する感じ。
if 文の分岐を無くせるという点で有用だと思う。例ではインターフェースとクラスを使っているが、現代のプログラミングだと以下のように匿名関数(lambda 式、アロー関数)を使うほうが多いような気がする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | type DiscountStrategy = (price: number) => number;
class ShoppingCart {
calculateFinalPrice(
originalPrice: number,
discountStrategy: DiscountStrategy
) {
return discountStrategy(originalPrice);
}
}
const cart = new ShoppingCart();
console.log(
"割引なし",
cart.calculateFinalPrice(100, (price) => price) // 第2引数がStrategyパターンになっている
); // 割引なし 100
console.log(
"固定料減額",
cart.calculateFinalPrice(100, (price) => price - 10)
); // 固定料減額 90
console.log(
"割引",
cart.calculateFinalPrice(100, (price) => price * 0.85)
); // 割引 85
|
もしこのパターンを知らない場合、以下のようにひたすら if 文を分岐させることになる。バリエーションが増えるとどんどん長くなる。他のメソッドでも同じことをやることになると爆発する。if 文の実装漏れがあるとバグが出る。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | class ShoppingCart {
calculateFinalPrice(originalPrice: number, discountStrategy: string) {
if (discountStrategy === "noDiscount") {
return originalPrice;
}
if (discountStrategy === "fixedAmountDiscount") {
return originalPrice - 10;
}
if (discountStrategy === "percentageDiscount") {
return originalPrice * 0.85;
}
}
}
const cart = new ShoppingCart();
console.log("割引なし", cart.calculateFinalPrice(100, "noDiscount")); // 割引なし 100
console.log("固定料減額", cart.calculateFinalPrice(100, "fixedAmountDiscount")); // 固定料減額 90
console.log("割引", cart.calculateFinalPrice(100, "percentageDiscount")); // 割引 85
|
WebSocket では JSON をやり取りして、受信側は JSON の中身によって処理を分岐したりするが、そういうときに Strategy パターンを使えればいいのになと思うことがある。しかし JSON は文字列であり、パースしてもメソッドを持たないオブジェクトであるため、Strategy パターンを導入することはできない気がする。残念ながら外部のクラスなり関数なりが if 文なり辞書なりで処理を分岐してやらないといけないと思う。