观察者模式又被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者模式属于行为型模式。
意图:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用
观察者模式使用三个类 Subject、Observer 和 Client。Subject 是被观察者,内部提供注册和反注册观察者方法以及状态发生变化通知所有观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
实例:
定义被观察者Suject,也根据自己需求可以定义为抽象类然后进行拓展。
public class Subject {
private ArrayList<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer) {
observers.add(observer);
}
public void detachOberver(Observer observer) {
observers.remove(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
定义观察者抽象类Observer以及具体的实现类
public abstract class Observer {
String TAG = "Observer";
abstract void update(int state);
}
public class BinaryObserver extends Observer {
@Override
void update(int state) {
Log.d(TAG, "BinaryObserver update: Binary = " + Integer.toBinaryString(state));
}
}
public class OctalObserver extends Observer {
@Override
void update(int state) {
Log.d(TAG, "OctalObserver update: Octal = " + Integer.toOctalString(state));
}
}
public class HexObserver extends Observer {
@Override
void update(int state) {
Log.d(TAG, "HexObserver update: Hex = " + Integer.toHexString(state).toUpperCase());
}
}
定义Client端,以及打印log
subject = new Subject();
subject.attach(new BinaryObserver());
subject.attach(new OctalObserver());
subject.attach(new HexObserver());
findViewById(R.id.btnRecognizer).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
subject.setState(15);
}
});
05-30 23:42:42.176 6585 6585 D Observer: BinaryObserver update: Binary = 1111
05-30 23:42:42.176 6585 6585 D Observer: OctalObserver update: Octal = 17
05-30 23:42:42.176 6585 6585 D Observer: HexObserver update: Hex = F
以上是自己定义观察者和被观察者,在JDK中已经定义了Observer接口和被观察者Observable,可以通过API查看具体的用法。观察模式逻辑比较简单,这篇简析希望有所帮助。