什么是观察者模式
* 观察者模式,又叫发布-订阅模式(Publist/Subscribe)模式;
* 定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象.
* 这个主题对象发生变化时,会通知所有的观察者对象,使它们能够自动更新自己
观察者模式的组成以及Demo
Subject
/**
* Subject类,主题对象/抽象通知者,一般用一个抽象类或接口实现.
* 把所有对观察者对象的引用保存在一个聚类中,每个subject可有任意数量的观察者.
* 提供接口,可以增加和删除观察者对象
*/
public interface Subject {
void attach(Observer observer);
void deattach(Observer observer);
String getState();
void setState(String state);
void notifyObservers();
}
Observer
/**
* 抽象观察者,为所有的具体观察定义一个接口,在得到subject的通知时更新自己.
* 这个方法叫做更新接口;
* 通过包含一个更新接口,这个接口通常包含了一个update(),这个方法被称为更新方法
*/
public interface Observer {
void update();
}
具体通知者
/**
* ConcreteSubject,叫做具体主题或者具体通知者,将有关状态存入具体观察者对象;
* 在具体观察的内部状态发生改变时,给所有登记过的观察者发出通知.
*/
public class Notifier implements Subject {
public String state;
List<Observer> mObservers=new ArrayList<>();
public Notifier(String state) {
this.state = state;
}
@Override
public void attach(Observer observer) {
mObservers.add(observer);
}
@Override
public void deattach(Observer observer) {
mObservers.remove(observer);
}
@Override
public String getState() {
return state;
}
@Override
public void setState(String state) {
this.state=state;
notifyObservers();
}
@Override
public void notifyObservers() {
for(Observer ob:mObservers){
ob.update();
}
}
}
具体观察者
/**
* ConcreteObserver类,具体观察者,实现由抽象观察者实现的接口,以便自身的状态与subject相协调.
* 具体观察者可以保存一个具体subject对象的引用.
*/
public class Movier implements Observer {
protected Subject mNotifier;
protected String name;
public Movier(Subject notifier, String name) {
mNotifier = notifier;
this.name = name;
}
@Override
public void update() {
Log.d("meee",name+","+ mNotifier.getState()+"电影!!");
}
}
public class Gamer implements Observer {
protected Subject mNotifier;
protected String name;
public Gamer(Subject notifier, String name) {
mNotifier = notifier;
this.name = name;
}
@Override
public void update() {
Log.d("meee",name+","+ mNotifier.getState()+"游戏!!");
}
}
观察者模式的应用场景
当一个对象的改变需要同时改变其他对象的时候,而且不需要知道具体需要多少个对象需要改变时;
观察者模式的作用
本质上就是在解除耦合,让耦合的双方都依赖抽象;
Subject发出通知时不需要知道谁是它的Observer,任意Observer也不需要知道其他的观察者;
观察者模式的缺点
尽管已经用了依赖倒转原则(依赖接口),但抽象通知者还是依赖抽象观察者(知晓observer有update方法)