【デザインパターン】ObserverとPubSubの違い

May 15th, 2021

はじめに

私は普段のフロントエンド開発においてAngularというフレームワークを使うことが多いのだが、Angularでは一般的にRxJSというライブラリーを用いて非同期処理やイベントハンドリングを行なうことが主流となっている。

RxJSはReactiveXと呼ばれるリアクティブプログラミング(*1)ライブラリー群の中でJavaScript向けに提供されているライブラリーで、ObserverパターンというGoF(*2)のソフトウェアデザインパターンに準拠して作られている。

私は長らくこのObserverパターンをPubSub(出版購読)パターンと同じものだと思っていたのだが、つい最近になって両者は別の概念だという事を知った。

よってこの記事では、ObserverパターンとPubSubパターンの違いについて私が勉強したことを簡単にまとめてみる。


Observerパターンとは

Observerパターンは、Wikipediaで次のように定義されている。

“The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.” - Observer pattern


日本語で要約すると、Subject(被・観察者)に何か変更があった際にObserver(観察者)に自動的に変更がNotify(通知)されるデザインパターンとされている。

このデザインパターンは、図を用いて以下のように表現することができる。

Observerデザインパターン


分かりやすく例を用いて説明すると、就職活動においてSubjectが募集企業とした時に、Observerを求職者として見なすと、募集枠に空きが出たタイミングで求職者に通知されるデザインパターンをObserverパターンと言う。

なお、Observerグループは集合体である(よってここではObserversと表記している)が、個々のObserverが担う役割は異なっており、それぞれのObserverは他のObserverの役割に関しては関与しない。


PubSubパターンとは

PubSubパターンは、Wikipediaで次のように定義されている。

“publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers.” - Publish–subscribe pattern

すなわち、Publisher(出版社)が直接的にイベントをSubscriber(購読者)に通知しない、と言う点でSubjectが直接イベントをObserverに通知するObserverパターンと異なっていることがわかる。

このデザインパターンでは、PublisherとSubscriberはお互いに存在を認知しておらず、代わりにEvent Busと呼ばれる仲介人(Broker)を介してイベントが伝達される。なお、Event Busの存在はPublisherとSubscriberから認知されている。

イベントはEvent Busによってフィルタリングされ、それぞれのSubscriberに合わせてデータが成形された上で渡される。

PubSubデザインパターン


先ほどの例を用いて説明すると、募集企業(Publisher)と求職者(Subscriber)はお互いにその存在を認知しておらず、募集枠に空きができたタイミングで人材紹介会社(Event Bus)が仲介してイベントを伝達するという役割を果たすことになる。

また、募集の条件(ポジション、給与、待遇)などは個々の求職者によって千差万別であり、求職者に合わせて人材紹介会社が募集内容を変更するデザインパターンであるとも言える。


まとめ

ObserverパターンではSubject(被・観察者)とObserver(観察者)がお互いの存在を認知し、直接イベントの変更を伝達するが、PubSubパターンではPublisher(出版社)とSubscriber(購読者)はお互いの存在を認知しておらず、Event Bu(仲介者)を通してのみ情報の伝達が発生する。

ObserverパターンにおいてはSubject(被・観察者)とObserver(観察者)がお互いの存在を認知しているが故に、適切なメソッドをゼロタイムで呼び出すことができるので、同期的な処理に向いているとされている。

対して、PubSubパターンではEvent Bus(仲介者)の存在が非同期的な処理を可能にする(故に、非同期的なアプリケーションに実装される)。


補足

  • *1 データをストリームとして捉え、ストリームの操作を宣言的に記述するプログラミングパラダイム
  • *2 Gang of Four:「Design Patterns: Elements of Reusable Object-Oriented Software」の著者である4人のプログラマーの総称

参考