观察者模式是一种行为设计模式,它使你能够定义一个订阅机制,可以在对象事件发生时通知多个“观察”该对象的其他对象。
模式的动机
观察者模式可以用来实现事件处理系统,如GUI事件。在这种情况下,我们可以将用户代码视为观察者,GUI事件管理器作为被观察者。事件管理器保存了一个列表,指向所有需要通知的对象,并且在状态改变时遍历它们。
模式的结构
观察者模式包括以下角色:
- Subject(主题):知道它的观察者。可以有任意多个观察者观察同一个主题。
- ConcreteSubject(具体主题):将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知。
- Observer(观察者):为那些在主题发生改变时需获得通知的对象定义一个更新接口。
- ConcreteObserver(具体观察者):维护一个指向具体主题对象的引用。存储有关状态,这些状态应与主题的状态保持一致。实现 Observer 的更新接口以使自身状态与主题的状态保持一致。
Ruby 实现
在Ruby中,我们可以通过使用模块和类来实现观察者模式。
定义主题类
-- -------------------- ---- ------- ----- ------- ------- ---------- --- ---------- ---------- - -- --- --- ---------------------- ---------- -- -------- --- --- ------------------------- --------------------------- --- --- ---------------- --------------- - ---------- --------------------- - --- --- ------------ ----------------------- --- ---
定义观察者类
class Observer attr_accessor :subject def update(subject) raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end
具体主题和观察者
-- -------------------- ---- ------- ----- --------------- - ------- ------------- ------ --- ---------- ----- ------ - - --- --- ----------------------- ---- ------ --------- --- ------------- ------ - --------- ---------------- --- --- ----- ---------------- - -------- --- ---------------- ----- - ---- --- --- --------------- ---- --------- ----- ------- ----------------- --- ---
使用观察者模式
-- -------------------- ---- ------- ------- - ------------------- --------- - ---------------------------- --------- - ---------------------------- ------------------------------- ------------------------------- ------------------------ ------------------------
以上代码展示了如何在Ruby中实现观察者模式。在这个例子中,ConcreteSubject
类是被观察的对象,它包含了状态,并且有一个方法用于改变状态并通知所有的观察者。ConcreteObserver
类则是具体的观察者,它们实现了 update
方法来响应主题状态的变化。
通过这种方式,我们可以很容易地扩展或修改我们的系统,而无需更改现有的代码。只需要添加新的观察者或者删除旧的观察者即可。