導入
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#の
eventやActionリストで実装できる - 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です。