设计模式(十六)—观察者模式

最后更新于:2022-04-01 16:26:27

**定义**:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。 ## 一般模式 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340bd8b1c.jpg) Subject被观察者 ---|定义被观察者必须实现的职责,它必须能够动态的增加、取消观察者,一般是抽象类或者实现类,完成管理观察者并通知观察者。 Observer观察者 ---|观察者接到信息后,进行update操作 ConcreteSubject具体的被观察者 ---|定义被观察者自己的业务逻辑,同时定义对那些事件进行通知 ConcreteObserver具体的观察者 ---|每个观察者在接收到信息后的处理反应是不同的,各个观察者有自己的处理逻辑。 ~~~ public class ObserverTest { public static void main(String[] args) { //创建一个呗观察者 ConcreteSubject con = new ConcreteSubject(); //创建一个观察者 Observer observer = new ConcreteObserver(); //添加到被观察者类中 con.addObserver(observer); //完成某项任务,实现更新 con.doSomething(); } } /** * 观察者接口,所有观察者要实现该接口。 * 实现方法, 处理不同的业务逻辑。 * @author admin * */ interface Observer{ public void update(); } /** * 具体的观察者实现类。 * @author admin * */ class ConcreteObserver implements Observer{ @Override public void update() { System.out.println("观察者接收到信息,去实现业务逻辑......."); } } /** * 被观察者抽象类, * 主要对观察者的操作,增加、删除、通知所有观察者等方法。 * @author admin * */ abstract class Subject{ //定义一个观察者集合 private List<Observer> observerList = new ArrayList<Observer>(); //添加一个观察者 public void addObserver(Observer o){ this.observerList.add(o); } //删除一个观察者 public void removeObserver(Observer o){ this.observerList.remove(o); } //通知所有的观察者 public void notifyObserver(){ for(Observer o : observerList){ o.update(); } } } /** * 被观察者的具体实现类, * 当被观察者完成某种操作以后, * 观察者会产生相应的更新操作 * @author admin */ class ConcreteSubject extends Subject{ public void doSomething(){ System.out.println("被观察者完成操作...."); super.notifyObserver(); } } ~~~ ## 一个例子: 韩国的韩非子是一个十分重要的任务,因此他身边被安插好多各个国家的间谍,来监视他的一举一动。 当韩非子有任何的行动间谍都要做相应的变化。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340bf37b9.jpg) ~~~ public class ObserverT { public static void main(String[] args) { //创建一个被观察者 HanFeiZi hfz = new HanFeiZi(); //创建一个李斯观察者 IObserver lisi = new Lisi(); //创建一个序言观察者 IObserver xuyan = new XuYan(); //添加观察者.. hfz.addOberver(lisi); hfz.addOberver(xuyan); //韩非子吃饭.. hfz.haveBreakfast(); } } /** * 被观察者的接口类, * 定义其日常的行为方法。 * @author admin * */ interface IHanFeiZi{ //吃饭 void haveBreakfast(); //娱乐 void haveFun(); } /** * 被观察者的接口类, * 定义其对身边间谍的增加、删除、通知所有间谍的方法 * @author admin * */ interface IObservable{ void addOberver(IObserver o); void removeObserver(IObserver o); void notifyObserver(String context); } class HanFeiZi implements IHanFeiZi,IObservable{ //定义一个监听者集合 private List<IObserver> observerList = new ArrayList<IObserver>(); @Override public void addOberver(IObserver o) { this.observerList.add(o); } @Override public void removeObserver(IObserver o) { this.observerList.remove(o); } @Override public void notifyObserver(String context) { for(IObserver o : observerList){ o.update(context); } } @Override public void haveBreakfast() { System.out.println("----韩非子开始吃饭了..."); this.notifyObserver("----韩非子在吃饭....."); } @Override public void haveFun() { System.out.println("----韩非子开始娱乐了..."); this.notifyObserver("----韩非子在娱乐....."); } } /** * 观察者接口类, * 实现该类的子类,对被观察者的举动进行相应的业务逻辑更新。 * @author admin * */ interface IObserver{ public void update(String context); } /** * 具体是观察者实现类.. * @author admin */ class Lisi implements IObserver{ @Override public void update(String context) { System.out.println("李斯接收到消息,向皇帝报告:"); this.reportToBoss(context); System.out.println("皇帝没有责罚我,我很开心..."); } private void reportToBoss(String info){ System.out.println("报告老板,"+info); } } class XuYan implements IObserver{ @Override public void update(String context) { System.out.println("序言接收到消息,想丈夫汇报:"); this.reportToHasband(context); System.out.println("序言表现很好.."); } public void reportToHasband(String info){ System.out.println("报告老公:"+info); } } ~~~ ## 观察者模式 的扩展 ---|java世界中的观察者模式 java.util.Observer接口和java.util.Observable实现类 为我们提供了观察者模式。 被观察者只需要继承Observable类,就可以实现对监听者的添加、删除、通知等方法, 观察者只要实现Observer接口,就可以完成相应的更新操作。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340c2353d.jpg) ~~~ public class ObserverT { public static void main(String[] args) { //创建一个被观察者 HanFeiZi hfz = new HanFeiZi(); //创建一个李斯观察者 Observer lisi = new Lisi(); //创建一个序言观察者 Observer xuyan = new XuYan(); //添加观察者.. hfz.addObserver(lisi); hfz.addObserver(xuyan); //韩非子吃饭.. hfz.haveBreakfast(); } } /** * 被观察者的接口类, * 定义其日常的行为方法。 * @author admin * */ interface IHanFeiZi{ //吃饭 void haveBreakfast(); //娱乐 void haveFun(); } class HanFeiZi extends Observable implements IHanFeiZi { @Override public void haveBreakfast() { System.out.println("----韩非子开始吃饭了..."); /* * 如果 hasChanged 方法指示对象已改变,则通知其所有观察者, * 并调用 clearChanged 方法来指示此对象不再改变。 */ super.setChanged(); super.notifyObservers("韩非子在吃饭..."); } @Override public void haveFun() { System.out.println("----韩非子开始娱乐了..."); /* * 如果 hasChanged 方法指示对象已改变,则通知其所有观察者, * 并调用 clearChanged 方法来指示此对象不再改变。 */ super.setChanged(); super.notifyObservers("韩非子在娱乐..."); } } /** * 具体是观察者实现类.. * @author admin */ class Lisi implements Observer{ @Override public void update(Observable o, Object arg) { System.out.println("李斯接收到消息,向皇帝报告:"); this.reportToBoss(arg); System.out.println("皇帝没有责罚我,我很开心..."); } private void reportToBoss(Object info){ System.out.println("报告老板,"+info); } } /** * 具体是观察者实现类.. * @author admin */ class XuYan implements Observer{ @Override public void update(Observable o, Object arg) { System.out.println("序言接收到消息,想丈夫汇报:"); this.reportToHasband(arg); System.out.println("序言表现很好.."); } public void reportToHasband(Object info){ System.out.println("报告老公:"+info); } } ~~~ 观察者模式的优点 ---|观察者和被观察者之间是抽象耦合 ---|建立一套触发机制 观察者模式的缺点: ---|观察者模式的效率问题 观察者的使用场景 ---|关联行为场景,需要注意的是,关联行为是可拆分的,而不是”组合“关系 ---|事件多级触发场景 ---|跨系统的消息交换场景,如消息队列的处理机制
';