Featured image of post 第10回-これがObserverパターンだ! - Perlでハニーポット侵入レーダーを作ろう

第10回-これがObserverパターンだ! - Perlでハニーポット侵入レーダーを作ろう

シリーズで作ってきた設計がGoFのObserverパターンそのものだったことを明かします。クラス対応表とPub/Subとの比較で理解を深めましょう。

@nqounetです。

前回でハニーポット侵入レーダーの司令室が完成しました。ログ・スコア・リスクレベル・アラートが連動する、なかなか本格的なシステムになりましたね。

最終回の今回は、ここまで作ってきた設計の正体を明かします。

実は有名なパターンだった

このシリーズで作った設計、実はObserverパターンというGoF(Gang of Four)のデザインパターンの1つです。

	classDiagram
    class Subject {
        +attach(observer)
        +detach(observer)
        +notify()
    }
    class Observer {
        <<interface>>
        +update(event)
    }
    class ConcreteObserverA {
        +update(event)
    }
    class ConcreteObserverB {
        +update(event)
    }
    Subject --> Observer : notifies
    ConcreteObserverA ..|> Observer
    ConcreteObserverB ..|> Observer

クラス対応表

私たちが作ったクラスと、Observerパターンの標準的な役割を対応させてみましょう。

パターン上の役割私たちのクラス責務
Subject(発行者)IntrusionHubObserverの管理と通知
Observer(購読者インターフェース)IntrusionObserver(Role)updateメソッドの契約
ConcreteObserver(具体的な購読者)RadarLogObserverログ出力
ConcreteObserverThreatScoreObserverスコア計算
ConcreteObserverRiskLevelObserverリスクレベル判定
ConcreteObserverAlertObserverアラート通知
Event(イベント)IntrusionEvent通知データ

Observerパターンの本質

Observerパターンの本質は「1対多の依存関係を定義し、一つのオブジェクトの状態が変化したら、依存するすべてのオブジェクトに自動的に通知する」ことです。

私たちのシステムでは、これが以下のように実現されています。

  • 1(Subject): IntrusionHub(侵入イベントの発生源)
  • 多(Observers): RadarLogObserver、ThreatScoreObserver、RiskLevelObserver、AlertObserver
  • 状態変化: 侵入イベントの発生
  • 自動通知: notifyによる一斉呼び出し

なぜObserverパターンが有効か

このパターンには以下の利点があります。

疎結合

SubjectはObserverの具体的な実装を知りません。「updateを持っている何か」としか認識していません。これにより、新しいObserverを追加しても既存コードへの影響がありません。

柔軟性

Observerを動的に追加・削除できます。深夜だけアラートをONにする、といった運用が可能です。

拡張性

開放閉鎖の原則(OCP)を自然に満たします。新機能は新しいクラスとして追加するだけ。

Pub/Subとの比較

Observerパターンと似た仕組みに「Pub/Sub(Publish-Subscribe)」があります。

項目ObserverPub/Sub
結合度SubjectはObserverを直接知っているPublisherはSubscriberを知らない
仲介者なしメッセージブローカーが仲介
通知同期的非同期的が多い
スケール小〜中規模大規模分散システム向け

Observerパターンはより直接的でシンプル、Pub/Subはより疎結合で大規模向けです。今回の侵入レーダーのようなアプリケーション内通知にはObserverが適しています。

注意点とデメリット

Observerパターンにも課題はあります。実運用で気をつけるべき点を挙げておきましょう。

注意点説明対策
通知順序が不定Observerの呼び出し順序は保証されない順序に依存しない設計にする
参照保持によるリークdetachを忘れるとObserverが解放されない不要になったら必ずdetach
大量通知の負荷Observerが増えるほど通知コストが増加必要なものだけ登録する

今回のシリーズではこれらの問題には深入りしませんでしたが、実際のプロジェクトでは意識しておくと良いでしょう。

デザインパターンを学ぶ意義

「パターンなんて覚えなくても動くコードは書ける」という意見もあります。確かにその通りです。

しかし、パターンを知っていると以下の利点があります。

  • 共通語彙: 「これObserverパターンね」で設計の意図が伝わる
  • 車輪の再発明を防ぐ: 先人の知恵を活用できる
  • 思考の引き出し: 問題に対する解決策の候補が増える

シリーズまとめ

全10回を通じて、以下のことを学びました。

テーマ学んだこと
第1回最小構成イベントクラスの設計
第2回破綻SRP/OCP違反の弊害
第3回クラス分離責務の分離
第4回Role契約インターフェースの定義
第5回司令塔Subject/Observerの関係
第6回動的登録柔軟な運用
第7回型チェック堅牢性の向上
第8回OCP実践拡張容易性
第9回統合完成達成感
第10回パターン設計知識の体系化

おわりに

このシリーズでは「知っている知識で動くものを作る → 破綻する → パターンで解決する」という流れを体験しました。

Observerパターンは、イベント駆動型のシステムでよく使われます。GUIのイベントハンドラ、ログシステム、通知機能など、応用範囲は広いです。

ぜひ、自分のプロジェクトでも活用してみてください。

お疲れさまでした!

参考リンク

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。