文章目录

观察者模式

观察者模式(Observer Pattern)也称公布订阅模式,它的目标是定义对象间一种一对多的依赖关系,使得每当一个对象扭转状态,则所有依赖于它的对象都会失去告诉并被自动更新。

观察者模式的类图如下图所:

观察者模式具备以下4个角色:

角色阐明
形象主题(Subject)角色该角色又称为“被观察者”,能够减少和删除观察者对象。
形象观察者(Observer)角色该角色为所有的具体观察者定义一个接口,在失去主题的告诉时更新本人。
具体主题(Concrete Subject)角色该角色又称为“具体被观察者”,它将无关状态存入具体观察者对象,在具体主题的外部状态扭转时,给所有注销过的观察者发出通知。
具体观察者(Concrete Observer)角色该角色实现形象观察者所要求的更新接口,以便使本身的状态与主题的状态相协调。

代码案例:

定义形象主题(Subject)角色类

package com.shixun.design.observer;/** * 形象主题:被观察者 */interface  Subject  {     // 注销一个新的观察者    public  void  attach(Observer obs);    // 删除一个注销过的观察者    public  void  detach(Observer obs);    // 告诉所有注销过的观察者对象    public  void  notifyObserver();}

定义形象观察者(Observer)角色类

package com.shixun.design.observer;/** * 形象观察者:为所有的具体观察者定义一个接口 */interface  Observer  {     // 更新办法    public  void  update();}

定义具体主题(Concrete Subject)角色类

package com.shixun.design.observer;import java.util.Enumeration;import java.util.Vector;/** * 具体主题:具体被观察者 */class  ConcreteSubject  implements  Subject  {     private Vector<Observer> obsVector = new Vector<Observer>();    // 注销一个新的观察者    public  void  attach(Observer obs)  {         obsVector.add(obs);    }    // 删除一个注销过的观察者    public  void  detach(Observer obs)  {         obsVector.remove(obs);    }    // 告诉所有注销过的观察者对象    public  void  notifyObserver()  {         for (Observer e : obsVector) {             e.update();        }    }    // 返回观察者汇合的Enumeration对象    public  Enumeration<Observer>  observers()  {         return obsVector.elements();    }    // 业务办法,扭转状态    public  void  change()  {         this.notifyObserver();    }}

定义具体观察者(Concrete Observer)角色类

package com.shixun.design.observer;/** * 具体观察者:实现形象观察者所要求的更新接口 */class  ConcreteObserver  implements  Observer  {     // 实现更新办法    public  void  update()  {         System.out.println(this+"收到告诉,并进行解决!");    }}

定义测试类:

package com.shixun.design.observer;import com.shixun.design.strategy.ConcreteStrategy;import com.shixun.design.strategy.Context;public class  Test  {     public  static  void  main(String[] args)  {         ConcreteSubject subject = new ConcreteSubject();        ConcreteObserver observer = new ConcreteObserver();        ConcreteObserver observer1 = new ConcreteObserver();        ConcreteObserver observer2 = new ConcreteObserver();        subject.attach(observer);        subject.attach(observer1);        subject.attach(observer2);        subject.change();    }}

运行后果如下:

观察者模式具备以下几个长处:

  • 观察者和被观察者之间是形象耦合。被观察者角色所晓得的只是一个具体观察者汇合,每一个具体观察者都合乎一个形象观察者的接口。被观察者并不意识任何一个具体的观察者,它只晓得它们都有一个独特的接口。因为被观察者和观察者没有严密的耦合在一起,因而它们能够属于不同的抽象化档次,且都非常容易扩大。
  • 反对播送通信。被观察者会向所有注销过的观察者发出通知,这就是一个触发机制,造成一个触发链。

察看模式的毛病如下:

  • 如果一个主题有多个间接或间接的观察者,则告诉所有的观察者会破费很多工夫,且开发和调试都比较复杂。
  • 如果在主题之间有循环依赖,被观察者会触发它们之间进行循环调用,导致系统解体。在应用观察者模式时要特地留神这一点。
  • 如果对观察者的告诉是通过另外的线程进行异步投递,零碎必须保障投递的程序执行。
  • 尽管观察者模式能够随时使观察者晓得所察看的对象产生了变动,然而观察者模式没有提供相应的机制使观察者晓得所察看的对象是如何发生变化。

利用场景

观察者模式的利用场景如下:

  • 关联行为场景。
  • 事件多级触发场景。
  • 跨零碎的音讯替换场景,如音讯队列的解决机制。