观察者模式定义
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
WIKI介绍:The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
角色
- Subject: 目标
- ConcreteSubject: 具体目标
- Observer: 观察者
- ConcreteObserver: 具体观察者
观察者模式应用
MVVM模式
MVVM是Model-View-ViewModel的简写。即模型-视图-视图模型。【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁。
它有两个方向:
一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。
这两个方向都实现的,我们称之为数据的双向绑定。
总结:在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信
角色分析,根据观察者定义角色有subject和observer。在实现了数据的双向绑定时,Model和View是subject,ViewModel是observer。
Model->View时,Model是目标,ViewModel是观察者,当Model发生变化时,ViewModel观察到变化并通知View更新。
View->Model时,View是目标,ViewModel是观察者,当View发生变化时,ViewModel观察到变化并通知Model更新。
应用
- WPF
- 前端框架,Vue、Angular等
- Android MVVM,Android应用架构指南中推荐MVVM
- 在JDK的java.util包中,提供了Observable类以及Observer接口,它们构成了Java语言对观察者模式的支持
观察者模式实现
public abstract class Subject {
List<Observer> observerList;
public abstract void attach(Observer observer);
public abstract void detach(Observer observer);
public abstract void notifyObservers();
public abstract int getState();
public abstract void setState(int state);
}
public abstract class Observer {
abstract void update(Subject subject);
}
public class ConcreteSubject extends Subject {
int state;
public ConcreteSubject(int state) {
this.state = state;
this.observerList=new ArrayList<>();
}
@Override
public void attach(Observer observer) {
this.observerList.add(observer);
}
@Override
public void detach(Observer observer) {
this.observerList.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer o:
this.observerList) {
o.update(this);
}
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
public class ConcreteObserver extends Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
void update(Subject subject) {
System.out.println("This is Observer"+this.name+". get subject state:"+subject.getState()+",update something");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Subject subject=new ConcreteSubject(1);
Observer observerA=new ConcreteObserver("A");
Observer observerB=new ConcreteObserver("B");
subject.attach(observerA);
subject.attach(observerB);
subject.notifyObservers();
subject.setState(2);
subject.notifyObservers();
System.out.println("detach:");
subject.detach(observerB);
subject.notifyObservers();