观察者模式介绍
观察者模式是一个使用率很高的模式,它最常用的地方是GUI系统,订阅–发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。
观察者模式的定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
观察者模式的使用场景
关联行为场景,需要注意的是,关联行为是可拆分的,而不是组合关系。
事件多级触发场景。
观察者模式的UML类图
Subject:抽象主题角色把所有观察者对象的引用保存在一个集合里,每个主题都可以任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject:具体主题,该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给索引注册过的观察者发出通知,具体主题角色又叫做具体观察者角色。
Observer:抽象观察者,该角色是观察者的抽象类,它定义了一个更新接口,使得在得到主题的更改通知时更新自己。
ConcreteObserver:具体的观察者,该角色实现抽象观察者角色所定义的更新接口,以便在主题的状态发生变化时更新自身的状态。
观察者模式的简单实现:
抽象观察者角色类:
public interface Observer {
public void update();
}
抽象主题角色类:
public abstract class Subject {
private List<Observer> list = new ArrayList<>();
public void attach(Observer observer) {
list.add(observer);
System.out.println("Attached an observer");
}
public void detach(Observer observer) {
list.remove(observer);
}
//通知所有注册的观察者对象
public void nodifyObservers(String newState) {
for(Observer observer : list){
observer.update();
}
}
}
具体主题角色类:
public class ConcreteSubject extends Subject {
private String state;
public String getState(){
return state;
}
public void change(String newState){
state = newState;
System.out.println("主题状态为:" + state);
this.nodifyObservers(newState);
}
}
具体观察者角色类
public class ConcreteObserver implements Observer {
private String observerState;
public ConcreteObserver(String state) {
this.observerState = state;
}
@Override
public void update() {
System.out.println("观察者状态为:" + observerState);
}
}
客户端:
public class Client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer = new ConcreteObserver("new state");
Observer observer1 = new ConcreteObserver("new state1");
Observer observer2 = new ConcreteObserver("new state2");
subject.attach(observer);//添加观察者到主题
subject.attach(observer1);
subject.attach(observer2);
subject.change("new State");//主题改变,会通知观察者,回调观察者update()方法
}
}
Attached an observer
Attached an observer
Attached an observer
主题状态为:new State
观察者状态为:new state
观察者状态为:new state1
观察者状态为:new state2
这是一个简单的观察这模式的实现,通过Subject主题的attach()方法注册观察者,当Subject主题改变的时候,会通知观察者回调update()方法,观察者通过自身的update()方法,做一些业务,比如修改GUI,获取数据等。
观察者模式在实际应用中很广,android广播接收器就是观察者模式,ListView的adapter的notifyDataSetChanged的方法。也是通知ListView的条目更新。