劇的ビフォ◯アフターで学ぶデザインパターン〜facade pattern〜
カレーを作るクラスを考える
玉ねぎきって、
じゃがいもをむいて切って、
カレールーをとかす。
そんな料理を実現するクラス群を作って考えてみます。
before
まずはfacade patternを使わずに書いてみます。
ソースコード
class Onion { cut() { console.log('玉ねぎが刻まれました'); } } class Potato { peel() { console.log('じゃがいもの皮をむきました'); } cut() { console.log('じゃがいものをきりました'); } } class CurryBase { dissolve() { console.log('ルーを溶かしました'); } } class Main { static cookingStart() { /** 玉ねぎ2個を刻む */ const onion1 = new Onion(); onion1.cut(); const onion2 = new Onion(); onion2.cut(); /** じゃがいも2個を剥いて切る */ const potato1 = new Potato(); potato1.peel(); potato1.cut(); const potato2 = new Potato(); potato2.peel(); potato2.cut(); /** カレーのルーを溶かす */ const curryBase = new CurryBase(); curryBase.dissolve(); } } Main.cookingStart();
クラス図
これを見ると、
使う側のクラス(Mainクラス)が
使われる側のクラスを3つも知っていることになります。
使う側と使われる側の依存性が高いといえます。
この場合、使われる側のクラスのメソッド名などを修正した際、
使う側のクラスも修正しなくてはいけません。
after
今度はfacade patternを使って書いてみます。
ソースコード
class Onion { cut() { console.log('玉ねぎが刻まれました'); } } class Potato { peel() { console.log('じゃがいもの皮をむきました'); } cut() { console.log('じゃがいものをきりました'); } } class CurryBase { dissolve() { console.log('ルーを溶かしました'); } } class Chef { cook() { /** 玉ねぎ2個を刻む */ const onion1 = new Onion(); onion1.cut(); const onion2 = new Onion(); onion2.cut(); /** じゃがいも2個を剥いて切る */ const potato1 = new Potato(); potato1.peel(); potato1.cut(); const potato2 = new Potato(); potato2.peel(); potato2.cut(); /** カレーのルーを溶かす */ const curryBase = new CurryBase(); curryBase.dissolve(); } } class Main { static cookingStart() { const chef = new Chef(); chef.cook(); } } Main.cookingStart();
クラス図
なんということでしょう。
先ほどMainクラスは3つのクラスのことを知っている必要がありましたが、
今は1つ(Chefクラス)だけ知っていればOKとなりました。
匠(facade)のお陰で随分疎結合な設計となりました。
PotatoやCurryBase等のクラスのメソッド名などを修正しても、
使う側のクラス(Main)は修正する必要はありません。
すばらしいですね。
まとめ
facade patternは、
使う側と
使われる側を疎結合にする
デザインパターンでした。
そうすることにより、
クラス修正による影響を使う側がうけないので、
修正に対して強くなります。