概要
Observerパターンは、オブジェクト(observable)とその依存関係(observers)の間の一対多の依存関係をモデル化するために使用できる。このパターンでは、observableは、関連する状態の変化をすべてのobserversに通知する責任がある。このパターンは、中央の状態が非中央の動作に影響を与える場合(分散イベント処理など)に特に有効だ。
以下の実行例では、あるフォーラム(observable、ステートフルな実体)を、複数の自然言語処理ボット(observers)が観測している様子をシミュレーションする。フォーラムに新しいポストが追加されると、ボットに通知される。各ボットは、新しい投稿を処理し、責任を果たす(処理イベントの実装は、このデモの範囲を超えているため、省略する)。
実装例
すべてのオブザーバーボットは、AbstractObserverBotクラスを継承する。すべてのボットは、新しい投稿を通知するためにフォーラムが呼び出すプロセスメソッドを共有しており、このイベントの処理に関しては、それぞれの子が独自の責任を負う。
class ObservableForum:
def __init__(self):
self._observer_bots = []
def add_observer_bot(self, new_bot):
if not any(isinstance(bot, new_bot.__class__) for bot in
self._observer_bots):
print("Add observer: {}".format(new_bot.__class__.__name__))
self._observer_bots.append(new_bot)
def remove_observer_bot(self, bot_to_remove):
for bot in self._observer_bots:
if isinstance(bot, bot_to_remove.__class__):
print("Remove observer: {}".format(bot.__class__.__name__))
self._observer_bots.remove(bot)
return None
def new_post(self, post):
self._notify_observers(post)
pass
def _notify_observers(self, post):
for bot in self._observer_bots:
bot.process(post)
class AbstractObserverBot():
def process(self, post):
print("> {} is processing new post".format(self.__class__.__name__))
class SentimentAnalyser(AbstractObserverBot):
pass
class SpamDetector(AbstractObserverBot):
pass
if __name__ == "__main__":
sa_bot = SentimentAnalyser()
sd_bot = SpamDetector()
forum = ObservableForum()
forum.add_observer_bot(sa_bot)
forum.add_observer_bot(sd_bot)
print("\n")
forum.new_post("sample post")
forum.remove_observer_bot(sd_bot)
forum.new_post("sample post2")