观察者模式定义了对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖者都会收到通知并且自动更新。
生活中很多地方用到这种模式,比如说天气预报订阅系统,报纸订阅系统等。
下面一个实例模拟以下发布—-订阅过程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
输出结果:
Java 为我们提供了 Observer 接口和 Observable 类,下面我们来介绍一下如何使用。
如何把对象变成观察者 ?
实现观察者接口,然后调用 Observable 对象的 addObserver() 方法。不在想当观察者对象的时候,调用 deleteObserver() 方法就可以了。
可观察者如何送出通知 ?
首先,需要继承 java.util.Observable 类产生可观察者类,然后需要两个步骤。
先调用 setChanged() 方法,标记状态已经改变的事实。
然后调用两种 notifyObservers() 方法中的一个 : notifyObservers() 或者notifyObservers(Object arg)
观察者如何接受通知?
观察者实现了更新的方法,但是方法的签名不太一样 : update(Observable o, Object arg)。 这个时候就可以实现两种不同的效果。如果我们将 Object 属性不指定,也就是只传递 Observable 对象的值,这个时候就是默认不推送给观察者任何信息,不过观察者可以通过被观察者提供的 get 方法主动获取消息(这里也暗示了一个信息,就是我们的观察者内部需要获得被观察者的引用)。如果这里我们指定了 Object 的对象,那么被观察者会将信息推送给观察者。
注意,以上我们提到的 update() 方法中的 Object 参数和被观察者中notifyObservers(Object o) 中的 Object 是对应的。
针对本实例:
这里Observer是抽象的观察者角色,Coder扮演的是具体的观察者角色;Obserable对应的是抽象的主题角色,DevteachFrontier则是具体的主题角色。Coder是具体的观察者角色,它订阅了DevteachFrontier这个具体的被观察者对象,当DevteachFrontier有更新时,会遍历所有 的Coder(观察者),然后给这些观察者发布一个更新消息,即调用Coder中的update方法,这样就达到了一对多的通知功能,在这个过程中,通知系统都是依赖Observer和Obserable这些抽象类,因此对于Coder和DevteachFrontier完全没有耦合,保证了订阅的灵活性,可扩展性。