【GoF】Observerパターンとは?Publish-Subscribeパターンとの違い

この記事からわかること
- GoFのObserverパターンとは?
- メリットデメリット
- オブジェクトの状態を観測する仕組みとは?
- subjectとobserverの関係と違い
- Publish-Subscribeパターンとの違い
index
[open]
\ アプリをリリースしました /
モバイルアプリ開発をしている中で設計を考えている時に登場したObserverパターンについて概要や特徴を自分の備忘録がてらまとめていきます。まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
Observerパターンとは?
Observer(オブザーバー)パターンとはオブジェクトの状態を観測し、その状態に応じてオブジェクトの更新を行う設計のことで、過去の技術者たちが後世にも活用できるようにとデザインパターン(GoFの23種類のデザインパターン)として切り出して公開しています。
おすすめ記事:【GoF】23種類のデザインパターンとは?Swiftでよく使う活用例
「Observer」は日本語で「観測者」などを意味する英単語であり、その言葉通り1つのオブジェクトを観測することで値の変更やイベントの発生を検知し、別のオブジェクトの状態を変化させたりといった任意の処理などを行わせる仕組みになっています。
そのためイベント駆動型のアプリケーションや1つのオブジェクトの状態変化が他のオブジェクトの状態や動作などにも影響を与える状態のアプリケーションなど、お互いの結合度が高くなっている際に結合を弱くし、柔軟性と拡張性を持たせるために活用されます。
アーキテクチャで見るとMVCでは「View-Model」、MVVMでは「View-ViewModel」「ViewModel-Model」間のデータの連携に活用されていることが多いです。
おすすめ記事:【Swift】MVVMアーキテクチャとは?ViewModelの役割
SubjectとObserverの役割
Observer(オブザーバー)パターンの設計構造として肝となるのが「観察される側(Subject=被写体)」と「観測する側(Observer)」の2つのオブジェクトです。まずはそれぞれに持たせるべき役割を整理しておきます。
Subjectオブジェクトの役割
- 観察される側
- 状態変化を通知する
- 観測する側(Observer)を管理(登録/削除など)するメソッドが用意
- 複数のObserverが登録可能
Subjectオブジェクトは観察される側のオブジェクトであり、状態変化やイベントなどを検知して登録されているObserverに対して通知する役割が必要になります。また観測する側であるObserverを管理するためのメソッドや登録されているObserverを何かしら(配列など)で保持しています。
Observerオブジェクトの役割
- 観察する側
- 状態変化通知を受け取れる
- 任意の処置を実行する
- Subjectに依存する(登録される必要がある)
Observerオブジェクトは観察する側のオブジェクトであり通知を受け取り自身の状態(プロパティやメソッドの呼び出し)を更新する役割を持たせます。例ではメソッド名を「receiveNotification」としましたが「update」や「onNotify」などが使われています。

メリット/デメリット
Observerパターンを導入することで得られるメリットはさまざまです。そもそもあるイベントを検知して処理を実行するだけであれば1つのクラスにイベントの検知と任意の処理を持たせれば済む話です。しかし同じイベントで新しく他の処理を実行させたくなった場合は追加するのは困難ですし、責務の切り分けも不透明になっていきます。 Observerパターンを活用することでイベントの検知と任意の処理を分離させることで柔軟性と拡張性が向上します。
メリット
- 責務の切り分け
- 状態変化に応じて分岐させた処置を簡単に実装
- 被通知者(Subject)と通知を受ける側(Observer)を疎結合にできる
- 通知の必要のないObserverを簡単に追加・削除
- 複数のObserverに対して同時に通知可能
- 拡張性と柔軟性が高まる
デメリット
- コールバック処理のネストが深くなり可読性が低下することがある
- Observerの数が多すぎると管理が複雑化
- Observerが複数ある場合処理の順序が不安定になる
Publish-Subscribeパターンとの違い
Observer(オブザーバー)パターンは別名としてPublish-Subscribe(出版-購読)パターンと呼ばれているようです。ですが両者は似ているようで少し異なります。個人的にはObserver(オブザーバー)パターンの派生として生まれたような感じに捉えていますが、厳密にどのような立ち位置にあるのか分からないので知ってる人がいたら教えてもらえると嬉しいです。
では両者の違いは何かというと仲介者が存在するか否かです。まずそもそも「Subject」と「Observer」と呼んでいた2つのオブジェクトは役割も少し変わり、名称も「Publish」と「Subscribe」に変わります。そしてさらに中間に「Broker(仲介人)」(メッセージブローカー/イベントブローカー)と呼ばれるイベント通知を管理する役割を持った存在を設けます。

Observerパターンでは「Subject」と「Observer」が直接やり取りをしていましたが、「Publish」と「Subscribe」はお互いの存在を知ることなく、全て「Broker」を通じてやり取りを行います。
中間に「Broker(仲介人)」を設けることで「Publish」と「Subscribe」が完全に分離されるため結合度が下がり拡張性も向上します。さらに複数の「Publish」と複数の「Subscribe」(多対多)を組み合わせた構造を構築しやすいのも大きなメリットになっているようです。
ご覧いただきありがとうございました。