本文へスキップ
BecomeCoder

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

振る舞い②:Observer / Mediator

ブラウザで完結

導入

Observerは「状態変化を購読者に通知」——前章のイベントがまさにこれ。Mediatorは「多対多の複雑な連携を、仲介役1つに集約」します。オブジェクト同士の直接依存を減らすのが狙いです。

図解

flowchart TB
    SUB["Subject(変化する側)"] -->|通知| O1["Observer A"]
    SUB -->|通知| O2["Observer B"]
    style SUB fill:#e1f5fe

サンプル

// Observer: 気温の変化を、登録された観測者すべてに通知する
var station = new WeatherStation();
station.Register(temp => Console.WriteLine($"表示器: {temp}度"));
station.Register(temp => Console.WriteLine($"警報: {(temp >= 35 ? "猛暑" : "通常")}"));

station.SetTemperature(36);
// 表示器: 36度 / 警報: 猛暑

class WeatherStation
{
    private readonly List<Action<int>> _observers = new();
    public void Register(Action<int> observer) => _observers.Add(observer);

    public void SetTemperature(int temp)
    {
        foreach (var observer in _observers)
            observer(temp);   // 全観測者へ通知
    }
}
  • Observer: 変化する側(Subject)が、購読者(Observer)へ変化を通知する。C#のeventActionリストで実装できる
  • Mediator: 部品同士が直接やり取りせず、仲介役を経由することで結合を下げる(チャットルーム等)
  • どちらもオブジェクト間の直接依存を減らす

演習

var publisher = new NewsPublisher();
publisher.Subscribe(news => Console.WriteLine($"購読者: {news}"));
publisher.Publish("速報");

// TODO: Subscribe(Action<string>) で購読者を登録し、Publish(string) で全員へ通知する
//       NewsPublisher を定義してください
___
  • 期待される出力: 購読者: 速報
ヒント1を見る

List<Action<string>>に登録し、Publishで全員に渡します

ヒント2を見る

class NewsPublisher { private readonly List<Action<string>> _subs = new(); public void Subscribe(Action<string> s) => _subs.Add(s); public void Publish(string news) { foreach (var s in _subs) s(news); } }

まとめ

  • Observerは状態変化を購読者に通知する(イベントの一般形)
  • Mediatorは多対多の連携を仲介役に集約する
  • オブジェクト間の直接依存を減らす

次回: 操作の要求化と責任の連鎖Command/Chain of Responsibilityです。

実際に動かしてみよう

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

C# — ブラウザ内で実行

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