引用百科
观察者模式(有时又被称为发布(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); } }3、观察者接口
//观察者接口 public interface Observer { public void update(String status); }4、具体观察者接口实现
//具体观察者类 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()方法,通知所有登记过的观察者对象。