首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

#每日一种设计模式# 观察者模式

2012-10-07 
#每天一种设计模式# 观察者模式??系统常常会出现这种情况:每一个部分需要知道整体的状态。比如Excel中,当你

#每天一种设计模式# 观察者模式

?

?

系统常常会出现这种情况:

每一个部分需要知道整体的状态。比如Excel中,当你修改了一个单元格的值,可能横列的sum需要改变,纵列的sum需要改变,根据这个单元格做的图需要改变,是否被修改的按钮需要激活... 如果没有一种很好的处理方式,导致的结果将是系统?highly integrated。

?

仔细分析,比如Excel的单元格,我们可以抽象出单元格是a source of news ,而其他部门是?receiver,接受单元格的改动的通知,然后进行自己的处理。

比如,单元格修改之后,通知计算总和的类来做相应的处理。

?

?

class Excel         attr_reader :cell         def initialize(value,sum)               @cell = value               @sum = sum         end         def cell=(value)               @cell = value               @sum.update         endendclass Sum         def update               puts "Got Excel Cell Changed"         endendsum = Sum.newexcel = Excel.new(10,sum)excel.cell = 11

?

在这个例子上,这一切完全ok。但是唯一的缺点是,Excel和Sum之间是硬连接(hard-wired)。比如,当cell改变的时候,除了Sum类,Graph类也需要得到通知,在这个例子上,我们只能修改cell=(value)这个函数。改动量的确不是很大,不过,Excel类并没有真的改变,只是因为增加一个receiver,却需要修改source所在的类。这总是有些不太合理吧。

?

? ? ? ok,让我们把事情做的彻底一点。

?

?

class Excel          attr_reader :cell         def initialize(value)               @cell = value               @observers = []          end          def cell=(value)                @cell = value                notify_observers           end           def notify_observers                 @observers.each do |observer|                        observer.update                  end           end           def add_observer(observer)                  @observers << observer           end           def delete_observer(observer)                   @observers.delete(observer)            endendclass Sum         def update               puts "Got Excel Cell Changed"         endendsum = Sum.newexcel = Excel.new(10)excel.add_observer(sum)excel.cell = 11

? ? ? 通过这种方式,source不需要知道有多少receiver对它感兴趣,而增加一个新的receiver也只需要调用add_observer方法即可。

? ? ??#每日一种设计模式# 观察者模式这样Observer模式的结构就已经展现在眼前了。

?


#每日一种设计模式# 观察者模式

GoF把source叫为subject class,而receiver较为observers.

?

the Ruby standard library 提供了一个Observable module让我们可以轻松实现Observer模式。

?

?

?

热点排行