導入
Facadeは「複雑なサブシステムに、単純な窓口を1つ提供」。Flyweightは「大量の同一データを共有して省メモリに」。Proxyは「本物への代理を立て、アクセス制御やキャッシュを挟む」。いずれも“間に1枚かませる”パターンです。
図解
flowchart LR
U["利用側"] --> FA["Facade(単純な窓口)"]
FA --> S1["複雑な部品A"]
FA --> S2["複雑な部品B"]
style FA fill:#e1f5fe
サンプル
// Facade: 複数の部品を1つの簡単な操作にまとめる
var home = new HomeTheaterFacade();
home.WatchMovie(); // スクリーンを下ろす / プロジェクタON / 再生開始
// Proxy: 本物へのアクセス前にログ(や権限チェック)を挟む
IService service = new LoggingProxy(new RealService());
service.Run(); // [ログ] 呼び出し前 / 本処理を実行
interface IService { void Run(); }
class RealService : IService { public void Run() => Console.WriteLine("本処理を実行"); }
class LoggingProxy : IService
{
private readonly IService _real;
public LoggingProxy(IService real) => _real = real;
public void Run()
{
Console.WriteLine("[ログ] 呼び出し前");
_real.Run(); // 本物へ委譲
}
}
class HomeTheaterFacade
{
public void WatchMovie()
{
Console.WriteLine("スクリーンを下ろす");
Console.WriteLine("プロジェクタON");
Console.WriteLine("再生開始");
}
}
- Facade: 複雑な内部を隠し、単純な入り口を提供する(
WatchMovie一発) - Flyweight: 同じ値を使い回して共有し、メモリを節約する(文字フォント等)
- Proxy: 本物の代理として、ログ・権限・遅延ロード・キャッシュを挟む
演習
IImage img = new LazyImageProxy("photo.jpg");
Console.WriteLine("まだ読み込まれない");
img.Display(); // 読み込み: photo.jpg / 表示: photo.jpg
// TODO: Display() が呼ばれて初めて "読み込み: ファイル名" を出す遅延ロードの
// LazyImageProxy を定義してください(Display で読み込み→表示の順に出力)
interface IImage { void Display(); }
___
- 期待される出力:
まだ読み込まれない読み込み: photo.jpg表示: photo.jpg(3行)
ヒント1を見る
Displayの中で「読み込み」出力→「表示」出力の順にします
ヒント2を見る
class LazyImageProxy : IImage { private readonly string _file; public LazyImageProxy(string file) => _file = file; public void Display() { Console.WriteLine($"読み込み: {_file}"); Console.WriteLine($"表示: {_file}"); } }
まとめ
- Facadeは複雑な内部への単純な窓口
- Flyweightは同一データの共有で省メモリ
- Proxyは本物の代理でアクセス制御・遅延・キャッシュを挟む
次回: 振る舞いパターンへ。アルゴリズムと状態のStrategy/Stateです。