本文へスキップ
BecomeCoder

C#デザインパターンコース · 第1章 デザインパターン · レッスン7

構造③:Facade / Flyweight / Proxy

ブラウザで完結

導入

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です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。