设计相关6--观察者模式

来源:互联网 发布:备案好的域名买卖 编辑:程序博客网 时间:2024/06/06 03:53

定义

观察者模式也叫订阅发布者模式。订阅者们订阅某主题,当主题数据或者状态发生变化时,通知订阅了本主题的订阅者们进行更新。

组成及类图

  • 抽象主题Subject
    (1) 抽象主题可以是一个抽象类或者一个接口。
    (2)拥有一个新数对象或者一个状态属性。
    (3)拥有一个观察者集合,存放订阅了本主题的观察者们。可在实例化主题时,实例化这个集合属性。
    (4)支持通知观察者们。当数据更新或者状态发生变化时,推送新数据给订阅了本主题的观察者们,通知他们进行自动更新。
    (5)支持添加某个观察者。
    (6)支持移除某个观察者。
  • 具体主题
    (1)实现抽象主题的各个抽象方法。
    (2)主题不用关心数据是何时变化的,如何变化的。当数据变化时,通过set方法将新数据传给主题,在set方法里通知观察者们。
  • 抽象观察者Observer
    (1)抽象观察者可以是一个接口或者一个抽象类。
    (2)拥有一个订阅的主题。
    (3)支持订阅主题成为观察者。
    (4)支持取消订阅,数据更新时不要再通知我了,i dont care!!
    (5)支持更新数据,然后干点啥。
  • 具体观察者
    (1)拥有一个抽象主题的引用。提供set方法支持主题的更改,并在set方法里进行订阅注册。
    (2)实现观察者抽象方法。

  • 类图
    稍后上传。。。

场景举例

某化妆品品牌的VIP会员注册功能。只有注册为VIP会员,才会收到本店的打折消息和优惠。当然,你是土豪的话,也可以随时退订。

模式总结

(1)观察者模式很好的降低了主题和观察者之间的耦合度。主题不用关心自己具体有哪些订阅者,订阅者可以随时订阅或者取消订阅主题,而不用更改主题代码。
(2)数据同步有两种方式,一种是观察者订阅主题,通过主题的get方法,从主题那里拿;另一种是观察者订阅主题,在主题通知观察者更新时,推送数据给观察者们。个人比较支持第二种,觉得主题不应该提供数据的get方法。因为提供get方法的话,观察者只要拥有主题的引用,不用订阅,不就可以拿到新数据了吗!?要知道,主题才是数据的拥有者,数据的分配权归主题所有,不是谁想拿就能拿的。
(3)主题拥有数据,主题怎么获得外界的新数据呢,大多数人肯定想通过set方法呗,可是这样的话,订阅者可能会通过主题引用更改数据。要注意set方法的访问权限。
(4)留下几个疑问:

为啥把主题抽象成接口或抽象类?
提高一个模块(接口、抽象类)的复用潜力,使我们设计的目标!

观察者模式就是一对多的依赖,不能是多对多的依赖吗?比如一个观察者订阅多个主题?

如果主体的数据来自外界其他模块,它就不得不通过set方法获得新数据,此时观察者们很可能通过这个set方法更改数据的!咋整呢??

0 0
原创粉丝点击