引用百科
观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
相关角色
观察者模式主要包括以下角色:
1、抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
2、具体主题(RealSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
3、抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
具体观察者(RealObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
具体实现
具体代码
1、抽象主题类
//抽象主题类
public abstract class Subject {
// 观察者集合
private List<Observer> list = new ArrayList<Observer>();
// 添加观察者
public void register(Observer observer) {
list.add(observer);
}
//删除
public void remove(Observer observer) {
if (list.contains(observer)) {
list.remove(observer);
}
}
public void change(String status) {
this.notifyObserver(status);
}
//通知所有观察者
private void notifyObserver(String status) {
for (Observer observer : list) {
observer.update(status);
}
}
}
2、主题具体实现类
//具体主题角色类
public class RealSubject extends Subject {
private String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public void change(String status) {
System.out.println("当前主题状态:" + status);
super.change(status);
}
}
//观察者接口
public interface Observer {
public void update(String status);
}
//具体观察者类
public class RealObserver implements Observer {
private String name;
private String innerStatus;
public RealObserver(String name) {
super();
this.name = name;
}
@Override
public void update(String status) {
this.innerStatus = status;
System.out.println("观察者" + name + ",状态:" + innerStatus);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5、客户端Client测试
public class Client {
public static void main(String[] args) {
// 创建主题
RealSubject subject = new RealSubject();
// 创建观察者
Observer observerA = new RealObserver("张三");
Observer observerB = new RealObserver("李四");
// 给主题添加观察者
subject.register(observerA);
subject.register(observerB);
// 改变主题内容状态
subject.change("start");
}
}
以上通过简单的代码实现了观察者模式,运行输出:
当前主题状态:start
观察者张三,状态:start
观察者李四,状态:start
在运行时,这个客户端首先创建了具体主题类的实例,以及一个观察者对象。然后,它调用主题对象的register()方法,将这个观察者对象向主题对象登记,也就是将它加入到主题对象的聚集中去。这时,客户端调用主题的change()方法,改变了主题对象的内部状态。主题对象在状态发生变化时,调用超类的notifyObservers()方法,通知所有登记过的观察者对象。