カレーを作るクラスを考える
玉ねぎきって、
じゃがいもをむいて切って、
カレールーをとかす。
そんな料理を実現するクラス群を作って考えてみます。
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は、
使う側と使われる側を疎結合にする
デザインパターンでした。
そうすることにより、
クラス修正による影響を使う側がうけないので、
修正に対して強くなります。