观察者模式思维导图
设计模式-观察者模式
1、定义
一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象得到通知并被自动更新。
(是关于多个对象想知道一个对象中数据变化情况。)
2、分类&别名
分类:行为型模式
别名:依赖、发布订阅
3、推数据&拉数据
推数据方式:指具体主题将变化后的数据全部交给具体观察者;
拉数据方式:指具体主题不将变化后的数据交给具体观察者,而是提供了获得数据的方法,可以调用具体主题提供的方法得到数据。(处理多主题应采用拉数据方式。)
4、适用场景
当一个对象数据更新需要通知其他对象,但又不希望与其他对象形成紧耦合;
当一个对象数据更新时,这个对象不知道具体有多少对象需要更新。
5、UML类图
四种角色:
主题 Subject:规定具体主题需实现的方法,比如:添加、 删除、通知观察者更新数据。
观察者 Observer:观察者规定更新数据的方法。
具体主题 ConcreteSubject:使用一个集合(如 ArrayList)存放观察者的引用。以便数据变化时通知观察者。
具体观察者 ConcreteObserver:存放具体主题引用的接口变量,以便具体主题将自己的引用添加到主题的集合中,使自己成为它的观察者或删除不成为其观察者。
6、代码实现
import java.util.ArrayList;
//step1. 主题 Subject:规定具体主题需实现的方法,比如:添加、 删除、通知观察者更新数据
interface Subject {
public void addObserver(Observer o);
public void deleteObserver(Observer o);
public void notifyObservers();
}
//step2. 观察者 Observer:观察者规定更新数据的方法
interface Observer {
public void update();
}
//step3. 具体主题 ConcreteSubject:使用一个集合(如 ArrayList)存放观察者的引
// 用。以便数据变化时通知观察者
class ConcreteSubject implements Subject{
ArrayList<Observer> observers = new ArrayList<Observer>();
public void addObserver(Observer o) {
if(!(observers.contains(o)))
observers.add(o);
}
public void deleteObserver(Observer o) {
if(observers.contains(o))
observers.remove(o);
}
public void notifyObservers() {
for(int i=0; i<observers.size(); i++) {
Observer observer = observers.get(i);
observer.update();
}
// 或者
// for(Observer observer:observers)
// observer.update();
}
}
//step4. 具体观察者 ConcreteObserver:存放具体主题引用的接口变量,以便具体主题
// 将自己的引用添加到主题的集合中,使自己成为它的观察者或删除不成为其观察者
class ConcreteObserver1 implements Observer{
Subject subject;
ConcreteObserver1(Subject subject) {
this.subject = subject;
subject.addObserver(this);
}
public void update() {
System.out.println("Concrete Observer 1");
}
}
class ConcreteObserver2 implements Observer{
Subject subject;
ConcreteObserver2(Subject subject) {
this.subject = subject;
subject.addObserver(this);
}
public void update() {
System.out.println("Concrete Observer 2");
}
}
//step5. Demo
public class TestAwen {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver1 observer1 = new ConcreteObserver1(subject);
ConcreteObserver2 observer2 = new ConcreteObserver2(subject);
subject.notifyObservers();
}
}
运行结果截图