定义:
也称发布订阅模式,它是一种在项目中经常使用的模式
定义对象间一种一对多的依赖关系,使得每个对象改变状态,则所有的依赖于他的对象都会收到通知并且自动更新
角色:
- 抽象主题角色:被观察者,定义增加,删除,通知方法
- 抽象观察者角色:为所有具体观察者提供一个接口,定义更新方法
- 具体主题角色:实现增,删,通知方法,存储对象。
- 具体观察者角色:实现更新方法
优点:
- 观察者和被观察之间是抽象耦合,容易扩展
- 支持广播通信
缺点:
- 观察者太多,通知时会花费很多时间
- 如果主题直接有循环依赖,被观察者会触发它们之间进行循环调用,倒置系统崩溃
- 观察者对所观察对象如何实现一无所知
场景:
- 关联行为场景
- 事件多级触发场景
- 跨系统的信息交换场景,如消息队列的处理机制
注意:
- 广播链的问题,一个观察者可以有双重身份,即时观察者也是被观察者,广播链一单建立,逻辑就比较复杂,可维护性非常差。一般在观察者模式中一般存在一个对象既是观察者也是被观察者,这样消息最多转发一次(传递俩次) 较易控制
- 异步处理问题,异步处理就要考虑线程安全和队列的问题
实例:通知对象做出更新
package 观察者模式1;
public interface Subject {
public void attach(Observer observer); //登记
public void detach(Observer observer); //删除
public void notifyOb(); //通知
}
package 观察者模式1;
public interface Observer {
public void update();
}
package 观察者模式1;
import java.util.Vector;
public class ConcreteSubject implements Subject{
private Vector<Observer> vector = new Vector<>();
@Override
public void attach(Observer observer) {
// TODO 自动生成的方法存根
vector.add(observer);
}
@Override
public void detach(Observer observer) {
// TODO 自动生成的方法存根
vector.remove(observer);
}
@Override
public void notifyOb() {
// TODO 自动生成的方法存根
for(Observer o:vector){
o.update();
}
}
}
package 观察者模式1;
public class ConcreteObserver implements Observer{
@Override
public void update() {
// TODO 自动生成的方法存根
System.out.println("我知道了");
}
}
package 观察者模式1;
public class He implements Observer{
@Override
public void update() {
// TODO 自动生成的方法存根
System.out.println("他知道了");
}
}
package 观察者模式1;
public class Every implements Observer{
@Override
public void update() {
// TODO 自动生成的方法存根
System.out.println("所有人都知道了");
}
}
package 观察者模式1;
public class Main {
public static void main(String []args) {
Subject subject = new ConcreteSubject();
Observer my = new ConcreteObserver();
Observer he = new He();
Observer every = new Every();
subject.attach(my);
subject.attach(he);
subject.attach(every);
subject.notifyOb();
}
}
我知道了
他知道了
所有人都知道了