定义
观察者模式:定义了一种对象间的一对多依赖关系,一旦被依赖对象改变状态,所有观察者都会得到通知并自动更新。
实例
我们在日常生活中,微信公众号的运作模式便是典型的观察者模式的实现,一旦公众号新推了内容,所有关注公众号的账号都会得到通知。
优缺点
观察者模式的优点是可以实现表示层与数据逻辑层的分离,可以在观察者与被观察者之间建立一个抽象的耦合,支持广播通信。
缺点是如果一个观察者的被观察者太多的话,通知动作会花费大量的时间。而且如果观察者与被观察者之间存在循环依赖的话,观察目标可能会触发它们的循环调用,造成系统崩溃。
类图
被观察者维护着一个观察者的集合,在有事件时循环通知集合中的观察者。
被观察者抽象规定了被观察者的行为,必须包括:新增观察者、删除观察者、通知观察者。
观察者抽象规定了观察者的行为,必须包括:接收通知。
示例
观察者抽象:
/** * @Author Nyr * @Date 2019/11/26 19:21 * @Description 观察者抽象 */ public interface Obsever { /** * @Author Nxy * @Date 2019/11/26 19:21 * @Param msg:通知消息 * @Return * @Exception * @Description 接收观察者通知的方法 */ public void update(String msg); }
被观察者抽象:
/** * @Author Nyr * @Date 2019/11/26 19:23 * @Description 被观察者抽象 */ public interface Subject { /** * @Author Nxy * @Date 2019/11/26 19:24 * @Param o:观察者对象 * @Return * @Exception * @Description 新增观察者对象 */ public void addObserver(Obsever o); /** * @Author Nxy * @Date 2019/11/26 19:25 * @Param o:观察者对象 * @Return * @Exception * @Description 删除观察者对象 */ public void removeObserver(Obsever o); /** * @Author Nxy * @Date 2019/11/26 19:26 * @Param msg:通知信息 * @Return * @Exception * @Description 通知所有观察者 */ public void notifyObservers(String msg); }
被观察者实例:
public class ConcreteSubject implements Subject { //观察者集合 private List<Obsever> obsevers=new LinkedList<>(); /** * @Author Nxy * @Date 2019/11/26 19:24 * @Param o:观察者对象 * @Return * @Exception * @Description 新增观察者对象 */ @Override public void addObserver(Obsever o){ obsevers.add(o); } /** * @Author Nxy * @Date 2019/11/26 19:25 * @Param o:观察者对象 * @Return * @Exception * @Description 删除观察者对象 */ @Override public void removeObserver(Obsever o){ obsevers.remove(o); } /** * @Author Nxy * @Date 2019/11/26 19:26 * @Param msg:通知信息 * @Return * @Exception * @Description 通知所有观察者 */ @Override public void notifyObservers(String msg){ for(Obsever o:obsevers){ o.update(msg); } } }
观察者实例:
public class ConcreteObserver implements Obsever { @Override public void update(String msg){ System.out.println("消费者 "+this.hashCode()+" 收到通知: "+msg); } }
Demo
public class Demo { public static void main(String[] args) { Subject s = new ConcreteSubject(); Obsever o0 = new ConcreteObserver(); Obsever o1 = new ConcreteObserver(); Obsever o2 = new ConcreteObserver(); Obsever o3 = new ConcreteObserver(); Obsever o4 = new ConcreteObserver(); Obsever o5 = new ConcreteObserver(); //注册观察者 s.addObserver(o0); s.addObserver(o1); s.addObserver(o2); s.addObserver(o3); s.addObserver(o4); s.addObserver(o5); //通知所有观察者 s.notifyObservers("通知1"); } }
六个观察者都收到了通知: