1.核心内容
Java中已经提供了良好的使用类
- 类 Observable
- 接口 Observer
内容举例:
例如一个天气App的天气获取到了最新的天气消息,此时说App是这个"被观察者"。
订阅了这个App天气的用户就是"观察者"。
被观察者和观察者是一对多的关系,一个被观察者可以有多个观察者。例子中只有一个App,但是可以有多个用户。
在例子中,当被观察者的消息需要更新时,就会及时的将最新的内容通知到各位订阅了消息通知的观察者。
两者依赖关系:观察者依赖被观察者,单向依赖。
2.应用场景
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
- 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
- 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
3.代码
被观察者
public class ConObservable extends Observable {
private String conetent;
public String getConetent() {
return conetent;
}
public void setConetent(String conetent) {
this.conetent = conetent;
// notify 必须加入下行代码才能完成通知
this.setChanged();
// 推模型
this.notifyObservers(conetent);
// 拉模型
// this.notifyObservers();
}
}
观察者
public class ConObserver implements Observer {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
@Override
public void update(Observable o, Object arg) {
//推
System.out.println(name +" 推:收到消息" +arg);
//拉
System.out.println(name +" 拉:收到消息" +
((ConObservable)o).getConetent());
}
}
步骤
1.实例被观察者
2.实例观察者,设置个人基本信息
3.注册观察者(观察者订阅了App的用户)
4.设置最新信息,发起通知。
测试代码
public class Test {
public static void main(String[] args) {
ConObservable c = new ConObservable();
ConObserver cb = new ConObserver();
cb.setName("小李");
ConObserver cc = new ConObserver();
cc.setName("阿达");
// 注册观察者
c.addObserver(cb);
c.addObserver(cc);
// 设置通知内容,内容改变通知触发内容
c.setConetent(" 这里是内容");
}
}
4.优点
1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
5.缺点
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
6.注意事项
1、JAVA 中已经有了对观察者模式的支持类。
2、避免循环引用。
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。