🛠️「戦術家」Strategyパターン と「架け橋」Bridgeパターンは形がおなじ
切り替えのStrategy(戦術) 分離のBridge(架け橋)
Strategy は合成 (composition)
ストラテジーで利用される、そもそものカプセル化の考え方の元になる、メイヤーの開放/閉鎖原則 原理主義
抽象化の川を超え、GoFのBridgeはウィンドウの実装分離・拡張で活用
処理系により実装が変わるケースがあるとする、さらにその処理系はやりたい抽象化とも関係ない、たが程よく抽象化したいとき、橋渡しが必要になる
実装が抽象化されるので途中で書き換えられる
実装が隠せる
ブリッジ、こういう時使おう
・実装が複数あって正直迷っている(処理系が違うとか)
・利用側に色んな意味で負担をかけたくない(余計な心配をかけたくない、とか)
function run() {
var screen = new Screen();
var audio = new Audio();
var hand = new Gestures(screen);
var mouse = new Mouse(audio);
hand.tap();
hand.swipe();
hand.pinch();
mouse.click();
mouse.move();
mouse.wheel();
log.show();
}
これがブリッジの例。スクリーンのジェスチャーをハンドがやり、オーディオをマウス操作するためにオブジェクトを橋渡ししている。ここではブリッジは構造。
ファクトリとの併用
Strategyに戻ってみる。
Strategyは改行についてのお説教が始まる。振る舞い=改行、構造=ウィンドウ。
function run() {
var package = { from: "76712", to: "10012", weigth: "lkg" };
// the 3 strategies
var ups = new UPS();
var usps = new USPS();
var fedex = new Fedex();
var shipping = new Shipping();
shipping.setStrategy(ups);
log.add("UPS Strategy: " + shipping.calculate(package));
shipping.setStrategy(usps);
log.add("USPS Strategy: " + shipping.calculate(package));
shipping.setStrategy(fedex);
log.add("Fedex Strategy: " + shipping.calculate(package));
log.show();
}
ストラテジの切り替え(ups,usps,fedex)が行われているのがわかる。例えがわかりづらいが、クロネコ、サガワ、ウーバーとかって分かれてると思えばよいか。
一般にコンテキストとStrategyとの結合は、Bridge パターンにおける抽象化と実装の結合より強固である。
時系列においてストラテジがその名の通り柔軟に戦略を変えていくために予め強い結合を求めるのとは対照的に、構造においてブリッジが二つのオブジェクトクラスを橋渡しする。
ブリッジにはimplいう接尾辞がついたが、出自についてはゆっくり見よう。
数式で見るストラテジパターン
ストラテジーパターンは、アルゴリズムをオブジェクトとしてカプセル化し、アルゴリズムを使用するクライアントとは独立にしてアルゴリズムを切り替え可能にするパターンです。
A=f(C,S)
ここで、Cはコンテキスト(アルゴリズムを使用する環境)、Sは選択された戦略(アルゴリズム)、Aはアルゴリズムの実行結果、fは選択された戦略に基づいてアルゴリズムを実行する関数です。
Dot
digraph StrategyPattern {
node [shape=record]
Context [label="{Context|+executeStrategy(): void\n+setStrategy(Strategy): void}"]
Strategy [label="{Strategy|+algorithmInterface(): void}"]
ConcreteStrategyA [label="{ConcreteStrategyA|+algorithmInterface(): void}"]
ConcreteStrategyB [label="{ConcreteStrategyB|+algorithmInterface(): void}"]
ConcreteStrategyC [label="{ConcreteStrategyC|+algorithmInterface(): void}"]
Strategy -> ConcreteStrategyA [arrowhead="none"]
Strategy -> ConcreteStrategyB [arrowhead="none"]
Strategy -> ConcreteStrategyC [arrowhead="none"]
Context -> Strategy [label="uses" dir="back"]
{rank=same; ConcreteStrategyA ConcreteStrategyB ConcreteStrategyC}
}
いいなと思ったら応援しよう!
お願い致します