Observer Pattern - Design Pattern i Ruby Chapter 5
注意点
更新頻度を考える。 考えなしにすべての変更時にobserverオブジェクトに通知すると、かなりの数の冗長な通知が飛び交ってしまう可能性がある。 どういったタミングで通知を行うかの戦略は考えておくべき。
変更の一貫性 上記の高新頻度にも似ているが、細かい情報の変更を全て通知していると、整合性が取れなくなるケースが考えられる。 どういった変更のまとまりで通知するかを考えておく必要がある。
バリエーション
ruby標準のobserver
module Observable (Ruby 1.8.7)
updateメソッドを実装したobserverオブジェクトを定義することで簡単に実装できる。
コードベースのobserver
observerオブジェクトにupdateメソッドを実装したクラスのオブジェクトではなく、Procオブジェクトを使うことで、より簡単にObserverオブジェクトを登録できる。
updateメソッドの引数
一番簡単な実装はシンプルにselfを渡す実装だけど、この場合はobserverがobservableオブジェクトの内容から変更箇所を特定するような処理が必要になったりする。
こういったことが問題になるようなケースでは、変更箇所ごとに細かいupdate_***系のメソッドを用意するといい。
ただこの場合だと標準のobserverモジュールが使えないため、自分でmoduleを定義する必要がある。
実践
NewsFeedの通知を受け取るような想定で実装
require 'observer' class NewsFeed include Observable def initialize @news = [] @next_news_id = 1 end def add_news(title) @news << { id: @next_news_id, title: title } @next_news_id += 1 changed end def publish notify_observers self end def getNewsAfter(id) @news.select {|news| news[:id] > id} end end class NewsListener def initialize @last_received_news_id = 0 end def update(news_feed) unread = news_feed.getNewsAfter @last_received_news_id @last_received_news_id = unread.last[:id] p unread end end news_feed = NewsFeed.new news_feed.add_observer NewsListener.new news_feed.add_news 'news1' news_feed.publish news_feed.add_news 'news2' news_feed.add_news 'news3' news_feed.publish