
Facade(ファサード)デザインパターンは、複雑なシステムの内部処理を「シンプルな窓口(Facade)」で隠すパターンです。
利用者は、
複雑な仕組みを知らなくても簡単に使えるようになる。
例えると、家電のリモコンのようなイメージ。
リモコンを押すだけで、電源・温度・モードなどを内部的に連動させて動かしてくれる処理などで使うと効果的です。
使われやすい場面
複雑なライブラリやAPIを、ラップして使いやすくしたい時に構築するパターンです。
システム全体を統一的に扱う「初期化」「シャットダウン」などの共通処理においても一元管理する意味でよく使われます。
ゲーム開発・Webフレームワーク・SDKなどで多用されますね。
サンプルコード1
一般的な複雑処理をまとめるファサード
複雑な内部システム
class CPU {
freeze() { console.log("CPU: freeze"); }
jump(position) { console.log(`CPU: jump to ${position}`); }
execute() { console.log("CPU: execute"); }
}
class Memory {
load(position, data) { console.log(`Memory: load data '${data}' at ${position}`); }
}
class HardDrive {
read(lba, size) {
console.log(`HardDrive: read ${size} bytes from ${lba}`);
return "OS data";
}
}
Facade(窓口)
class ComputerFacade {
constructor() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
startComputer() {
console.log("=== Starting computer ===");
const bootData = this.hardDrive.read(0, 1024);
this.cpu.freeze();
this.memory.load(0, bootData);
this.cpu.jump(0);
this.cpu.execute();
console.log("=== Computer started ===");
}
}
利用側
const computer = new ComputerFacade();
computer.startComputer();
ポイント解説
CPU, Memory, HardDrive は細かい処理を持つ「内部の複雑なコンポーネント」です。
ComputerFacade がそれらをまとめて呼び出し、「簡単なAPI」として提供しています。
ユーザーは startComputer() だけ知っていればOK。
まとめて処理してくれる便利なメソッドが、ファサードですね。
サンプルコード2
通知・サウンド・ログ表示をまとめて扱うFacade
個別のAPIクラス群
class NotificationAPI {
send(message) {
if (Notification.permission === "granted") {
new Notification(message);
} else {
console.log("🔔 通知が許可されていません");
}
}
}
class SoundAPI {
playBeep() {
const audio = new Audio("https://actions.google.com/sounds/v1/alarms/beep_short.ogg");
audio.play();
}
}
class LogAPI {
write(message) {
console.log(`[LOG] ${new Date().toLocaleTimeString()} - ${message}`);
}
}
Facade(統一インターフェース)
class AlertFacade {
constructor() {
this.notifier = new NotificationAPI();
this.sound = new SoundAPI();
this.logger = new LogAPI();
}
async alert(message) {
this.logger.write(`Alert triggered: ${message}`);
// 通知許可を確認
if (Notification.permission !== "granted") {
await Notification.requestPermission();
}
this.notifier.send(message);
this.sound.playBeep();
}
}
使用例
const alertSystem = new AlertFacade();
// 1行で「通知+音+ログ」をまとめて実行
document.getElementById("alertBtn").addEventListener("click", () => {
alertSystem.alert("処理が完了しました!");
});
ポイント解説
NotificationAPI, SoundAPI, LogAPI は、それぞれバラバラのブラウザAPI。
AlertFacade がそれらを まとめてひとつの窓口(alert)として提供しています。
使う側は、細かいAPIの違いや初期化方法を気にせず、alertSystem.alert("メッセージ") だけでOK。
メリット
・コードの見通しが良くなる。
・依存関係が減る(クライアントが内部実装を知らなくていい)。
・システム変更の影響範囲を限定できる。
デメリット
・ファサードが肥大化すると「God Object(神クラス)」になりやすい。
・内部の詳細操作をしたい場合、Facade経由だと柔軟性が落ちる。
・抽象化が過剰だと、逆に分かりづらくなる。
あとがき
複数の実行処理をまとめる窓口的な役割がファサードです。
init()や、set()のようんあ名称で関数を作るイメージと同じですね。
効率性は増しますが、依存問題に陥らないように設計しないといけないので、これも経験して他のデザインパターンと組み合わせて堅牢な設計ができるようになるといいでしょう。
0 件のコメント:
コメントを投稿