1. 观察者模式
观察者模式属于设计模式中的行为型模式,主要用于对象间存在一对多的关系的时候。
- 作用:在一对多的对象关系中,当主对象的状态发生改变时,所有依赖于它的对象都将会被自动更新并得到通知。
- 解决的问题:向其它对象通知主对象的改变。
- 何时使用:当主对象的状态发生改变时,所有依赖于它的对象都将得到通知。
- 使用场景:
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
2.在微信公众服务中的实现示例
subject.java 主对象接口
package com.example.jingbin.designpattern.observer.interfaces;
/**
* Created by jingbin on 2016/10/21.
* 专题接口,所有的主题必须实现此接口
*/
public interface Subject {
/**
* 注册一个观察者
*/
public void registerObserver(Observer observer);
/**
* 移除一个观察者
*/
public void removeObserver(Observer observer);
/**
* 通知所有观察者
*/
public void notifyObservers();
}
ObjectFor3D.java 实现主对象
package com.example.jingbin.designpattern.observer.classs;
import com.example.jingbin.designpattern.observer.interfaces.Observer;
import com.example.jingbin.designpattern.observer.interfaces.Subject;
import java.util.ArrayList;
/**
* Created by jingbin on 2016/10/21.
* 接下来3D服务号的实现类:
*/
public class ObjectFor3D implements Subject {
private ArrayList<Observer> observers = new ArrayList<>();
/**
* 3D 彩票的号码
*/
private String msg;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int index = observers.indexOf(observer);
if (index >= 0) {
observers.remove(index);
}
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(msg);
}
}
/**
* 主题更新信息
*/
public void setMsg(String msg) {
this.msg = msg;
notifyObservers();
}
}
Observer.java 观察者接口
package com.example.jingbin.designpattern.observer.interfaces;
/**
* Created by jingbin on 2016/10/21.
* 所有观察者需要实现此接口
*/
public interface Observer {
public void update(String msg);
}
ObserverUser1.java 第一个观察者的实现
package com.example.jingbin.designpattern.observer.classs;
import android.util.Log;
import com.example.jingbin.designpattern.observer.interfaces.Observer;
import com.example.jingbin.designpattern.observer.interfaces.Subject;
/**
* Created by jingbin on 2016/10/21.
* 模拟第一个使用者
*/
public class ObserverUser1 implements Observer {
public ObserverUser1(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String msg) {
Log.e("-----ObserverUser1 ", "得到 3D 号码:" + msg + ", 我要记下来。 ");
// Toast.makeText(PatternApplication.getInstance(), "-----ObserverUser1 得到 3D 号码:" + msg, Toast.LENGTH_SHORT).show();
}
}
ObserverUser2.java 第二个观察者的实现
package com.example.jingbin.designpattern.observer.classs;
import android.util.Log;
import com.example.jingbin.designpattern.observer.interfaces.Observer;
import com.example.jingbin.designpattern.observer.interfaces.Subject;
/**
* Created by jingbin on 2016/10/21.
* 模拟第二个使用者
*/
public class ObserverUser2 implements Observer {
public ObserverUser2(Subject subject) {
subject.registerObserver(this);
}
@Override
public void update(String msg) {
Log.e("-----ObserverUser2 ", "得到 3D 号码:" + msg + ", 我要告诉舍友们。");
// Toast.makeText(PatternApplication.getInstance(), "-----ObserverUser2 得到 3D 号码:" + msg, Toast.LENGTH_SHORT).show();
}
}
测试
// 创建服务号
objectFor3D = new ObjectFor3D();
// 创建两个订阅者
observerUser1 = new ObserverUser1(objectFor3D);
observerUser2 = new ObserverUser2(objectFor3D);
// 两个观察者,发送两条信息
objectFor3D.setMsg("201610121 的3D号为:127");
objectFor3D.setMsg("20161022 的3D号为:000");
运行结果
如上所示,观察者模式实现了当主对象改变时,其它对象都将会被自动更新
3. 观察者模式的优点和缺点
- 优点:
- 观察者与被观察者之间没有紧密耦合,主对象只知道一个观察者列表,并不知道任何一个观察者
- 当主对象的数据改变时,会对观察者发出通知,观察者的数据也随之改变
- 缺点:
- 如果一个主对象的观察者有很多,通知观察者会耗费大量的时间
- 如果主对象和观察者之间存在循环依赖,会导致系统崩溃
- 观察者不知道主对象是如何变化的,只知道主对象发生了变化