Java 观察者模式
1. 什么是观察者模式
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样。在一片森林中,各种生物彼此依赖和约束,形成一个个生物链。一种生物的状态变化会造成其他一些生物的相应行动,每一个生物都处于别的生物的互动之中。
同样,一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其他的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。
2. 一个实例
- 抽象主题类
Subject
/**
* 主题抽象类
* @author jinzhihong
*/
public abstract class Subject {
/**
* 保存注册对象
*/
private List<Observer> observerList = new ArrayList();
/**
* 注册观察者对象方法
* @param observer
*/
public void attach(Observer observer){
observerList.add(observer);
System.out.println(" 注册了一个观察者 ");
}
/**
* 删除观察者对象
* @param observer
*/
public void detach(Observer observer){
observerList.remove(observer);
System.out.println(" 删除了一个观察者 ");
}
/**
* 通知所有已经注册的观察者更新状态
* @param newState
*/
public void notifyObservers(String newState){
for (Observer observer: observerList){
observer.update(newState);
}
}
}
- 具体主题类
ConcreteSubject
/**
* 具体主题类,继承抽象主题,定义change 状态方法
* @author jinzhihong
*/
public class ConcreteSubject extends Subject {
private String state;
public String getState() {
return state;
}
/**
* 定义改变新状态方法并通知已注册的观察者
* @param newState
*/
public void change(String newState) {
state = newState;
System.out.println(" 通知观察者新状态: " + state);
// 状态发生改变,通知观察者
this.notifyObservers(state);
}
}
- 观察者接口
Observer
/**
* 观察者接口
* @author jinzhihong
*/
public interface Observer {
/**
* 定义状态更新接口
* @param state
*/
void update(String state);
}
- 具体观察者实现接口
ConcreteObserver
/**
* 定义具体观察者实现观察者接口
*
* @author jinzhihong
*/
public class ConcreteObserver implements Observer {
// 状态
private String state;
/**
* 更新状态
*
* @param state
*/
@Override
public void update(String state) {
this.state = state;
System.out.println(" 更新观察者状态: " + state);
}
}
Client
执行
/**
* @author jinzhihong
*/
public class Client {
public static void main(String[] args) {
// 创建主题
ConcreteSubject subject = new ConcreteSubject();
// 创建观察者对象
Observer observer = new ConcreteObserver();