建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
观察者模式(
Observer Pattern
):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish
/Subscribe
)模式、模型-视图(Model
/View
)模式、源-监听器(Source
/Listener
)模式或从属者(Dependents
)模式。
观察者模式是一种对象行为型模式。
观察者模式包含如下角色:
Subject
: 目标(抽象的被观察着)ConcreteSubject
: 具体目标(具体的被观察者)Observer
: 观察者ConcreteObserver
: 具体观察者首先,是观察者接口:
/**
* 观察者接口
* Created by blinkfox on 16/7/14.
*/
public interface Observer {
// 更新的方法
public void update();
}
接下来,是具体的观察者类:
/**
* 具体的观察者.
*
* Created by blinkfox on 16/7/15.
*/
public class ConcreteObserver implements Observer {
/**
* 实现更新方法.
*/
@Override
public void update() {
System.out.println("接收到信息,并进行处理...");
}
}
然后,是被观察者的抽象类:
/**
* 被观察者的抽象类.
*
* Created by blinkfox on 16/7/14.
*/
public abstract class Subject {
/** 定义一个观察者的集合. */
private List<Observer> observers = new ArrayList<Observer>();
/**
* 增加一个观察者.
*
* @param o
*/
public void addObserver(Observer o) {
this.observers.add(o);
}
/**
* 删除一个观察者.
*
* @param o
*/
public void delObserver(Observer o) {
this.observers.remove(o);
}
/**
* 通知所有观察者.
*/
public void notifyObservers() {
for (Observer o: observers) {
o.update();
}
}
}
具体的被观察者:
/**
* 具体的被观察者.
*
* Created by blinkfox on 16/7/15.
*/
public class ConcreteSubject extends Subject {
/**
* 具体的业务.
*/
public void doSomething() {
super.notifyObservers();
}
}
最后,是用于测试观察者模式的客户端场景类:
/**
* 观察者模式客户端场景类.
*
* Created by blinkfox on 16/7/15.
*/
public class ObserverClient {
public static void main(String[] args) {
// 创建一个被观察者和观察者.
ConcreteSubject sub = new ConcreteSubject();
Observer obs = new ConcreteObserver();
// 观察者观察被观察者.
sub.addObserver(obs);
// 观察者开始活动了.
sub.doSomething();
}
}
publish-subscribe
)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通。观察者模式的优点:
观察者模式的缺点:
在以下情况下可以使用观察者模式:
观察者模式在软件开发中应用非常广泛,如某电子商务网站可以在执行发送操作后给用户多个发送商品打折信息,某团队战斗游戏中某队友牺牲将给所有成员提示等等,凡是涉及到一对一或者一对多的对象交互场景都可以使用观察者模式。
java.util
包中,提供了Observable
类以及Observer
接口,它们构成了Java语言对观察者模式的支持。