简单说两句
观察者模式,是对象行为型模式中的一种,有的时候人们也叫他发布/订阅模式。当我们需要在一个对象状态改变的时候通知到其它对象,这时候就可以考虑一下观察者模式。
细思不恐
主旨
在设计模式中,观察者模式的主旨则是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
解惑
在上面我们说到,有时观察者模式也称发布/订阅模式,那到底有啥区别呢?其实发布订阅模式是处于广义上的观察者模式,因为他是最常用的一种观察者模式的实现。
发布订阅模式相对观察者多了一个事件的通道,因为在观察者模式中,观察者(Observer)需要直接订阅目标(Subject)事件,在目标发出内容更改事件时,直接接收内容事件并做出响应。在发布订阅模式中订阅者需要从时间的通道中订阅事件,这样从发布者接收事件以及向订阅者发布事件,两者并没有产生依赖的关系。
具体代码上的区别,有兴趣的朋友可以在下方留言,下次可以出一个小分支。
实现方式
在上面的介绍中,我们大概知道了在观察者模式中,有这么两种主角色:
- Subject(被观察者)
被观察者必须要有添加观察者、删除观察者和提醒观察者的方法。
- Observer(观察者)
观察者要有更新方法,用来做出响应在状态改变调用提醒方法后。
Java中已经提供了观察者模式的实现,我们不需要再定义观察者和目标接口(被观察者),也不需要维护观察者的注册信息。可以继承Observable类实现被观察者目标对象,实现Observer接口完成具体的观察者对象,其中提供了update方法获取相应事件信息。
在这里为了方便说明观察者的基本原理,自己实现一个简单的案例。
首先抽象一个观察者类,里面有一个抽象方法更新状态。
public abstract class Oberver{
public abstract void Update();
}
然后再写一个抽象被观察者类。
public abstract class Subject{
//增加
public abstract void Attach(Observer observer);
//移除
public abstract void Detach(Observer observer);
//通知
public abstract void Notify();
}
具体上面两个类:
//具体的观察者
public class ConcreteObserver extends Observer{
@Override
public void Update() {
System.out.println("状态改变,更新状态");
}
}
//具体被观察者类
public class ConcreteSubject extends Subject {
//定义集合存储观察者
List<Observer> list=new ArrayList<Observer>();
//增加观察者
@Override
public void Attach(Observer observer) {
list.add(observer);
}
@Override
public void Detach(Observer observer) {
list.add(observer);
}
@Override
public void Notify() {
//遍历集合观察者对象
for(Observer observer:list){
observer.Update();
}
}
}
接下来我们就可以写测试类了:
public class ObserverDemo {
public static void main(String[] args) {
//创建被观察者对象
ConcreteSubject csb=new ConcreteSubject();
//创建观察者对象
ConcreteObserver cob=new ConcreteObserver();
//将观察者添加到被观察者的通知名单内
csb.Attach(cob);
//被观察者发出通知,观察者接受通知更新状态
csb.Notify();
}
}
//输出
“状态改变,更新状态”
就这样,一个简单的观察者模式的案例就结束了。当然一个复杂的应用中,我们肯定需要一个完整而且适用与多线程以及异步系统,因为观察者模式大都应用与这两中系统,所以也需要考虑线程安全的问题。下次会介绍更加详细完整的观察者的实现方式。
写在最后
因为每一篇的篇幅不宜过长,所以本打字员尽量在精简自己所写的内容,尽量能够多容扩一些知识点,但是具体的知识横向扩展可能就有一点欠缺,这也算是对自己的一种锻炼,希望大家能够一起进步,怎么样,在下面留个言吐槽一下本渣渣吧。(逃
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。