发布网友 发布时间:2024-10-02 03:17
共1个回答
热心网友 时间:2024-10-10 09:09
(一)什么是观察者模式我们都关注了某个公众号,当这个公众号发文章时,所有关注它的人都会收到一条消息通知。这种当一个对象被修改时,会自动通知依赖它的对象的动作抽象为设计模式就是观察者模式
(二)观察者模式中的角色观察者模式中主要有四个角色:
Subject:被观察对象的抽象类,这个角色还承担了注册观察者和删除观察者的方法。
ConcreteSubject:具体的被观察对象,在开头的例子中,某个公众号就是一个具体的被观察对象。
Observer:观察者的接口,负责接收被观察对象的状态变化并更新。
ConcreteOberver:具体的观察者,在开头的例子中,每个关注公众号的人就是具体的观察者。
(三)观察者模式的案例只看概念很难理解这种设计模式究竟是干什么的,接下来就通过一个具体的例子来感受一下,这个例子还是采用文章开头公众号的例子。 首先定义Observer接口,负责更新操作。
public?interface?Observer?{????/**?????*?更新操作?????*?@param?subject?????*/????public?abstract?void?update(Subject?subject);}上面代码中的Subject是被观察对象的抽象类,这个类定义了添加观察者、删除观察者、通知观察者的方法,并定义了获取标题和生成文章的两个抽象方法:
public?abstract?class?Subject?{????/**?????*?记录所有的观察者?????*/????private?ArrayList<Observer>?observers?=?new?ArrayList<>();????/**?????*?添加观察者?????*?@param?observer?????*/????public?void?addObservers(Observer?observer){????????observers.add(observer);????}????/**?????*?删除观察者?????*?@param?observer?????*/????public?void?deleteObservers(Observer?observer){????????observers.remove(observer);????}????/**?????*?通知所有的观察者?????*/????public?void?notifyObservers(){????????for(Observer?observer:observers){????????????observer.update(this);????????}????}????/**?????*?获取文章标题?????*/????public?abstract?String?getTitle();????/**?????*?生成一篇文章?????*/????public?abstract?void?createArticle();}接着定义具体的被观察对象,这里是一个具体的公众号,并实现获取标题和创建文章的抽象方法:
public?class?ConcreteSubject?extends?Subject{????private?String?title;????@Override????public?String?getTitle()?{????????return?title;????}????@Override????public?void?createArticle()?{????????System.out.println("创建了一篇文章");????????this.title="这是文章标题";????????this.notifyObservers();????}}接下来创建两个观察者:
public?class?OneObserver?implements?Observer{????@Override????public?void?update(Subject?subject)?{????????System.out.println("One收到了一篇推送,标题为"+subject.getTitle());????}}public?class?TwoObserver?implements?Observer{????@Override????public?void?update(Subject?subject)?{????????System.out.println("Two收到了一篇推送,标题为"+subject.getTitle());????}}最后通过Main类进行测试:
public?class?Main?{????public?static?void?main(String[]?args)?{????????//创建具体的被观察者对象????????Subject?concreteSubject?=?new?ConcreteSubject();????????//创建两个具体的观察者????????Observer?oneObserver?=?new?OneObserver();????????Observer?twoObserver?=?new?TwoObserver();????????//两个具体的观察者关注了被观察者对象????????concreteSubject.addObservers(oneObserver);????????concreteSubject.addObservers(twoObserver);????????//被观察者对象创建了一篇文章????????concreteSubject.createArticle();????????//第一个观察者取消关注????????concreteSubject.deleteObservers(oneObserver);????????//被观察者对象又创建了一篇文章????????concreteSubject.createArticle();????}}最终的运行结果如下:
创建了一篇文章One收到了一篇推送,标题为这是文章标题Two收到了一篇推送,标题为这是文章标题创建了一篇文章Two收到了一篇推送,标题为这是文章标题(四)观察者模式在源码中的应用在JDK的java.util包下,直接提供了观察者模式所需要的Observer和Subject对象。其中Observer对象和我在第三章定义的十分相似:
package?java.util;public?interface?Observer?{????void?update(Observable?o,?Object?arg);}Subject对象在这个包下名称叫做Observable,包含了添加观察者,删除观察者等操作。
package?java.util;public?class?Observable?{????private?boolean?changed?=?false;????private?Vector<Observer>?obs;????public?Observable()?{????????obs?=?new?Vector<>();????}????public?synchronized?void?addObserver(Observer?o)?{????????if?(o?==?null)????????????throw?new?NullPointerException();????????if?(!obs.contains(o))?{????????????obs.addElement(o);????????}????}????public?synchronized?void?deleteObserver(Observer?o)?{????????obs.removeElement(o);????}????public?void?notifyObservers()?{????????notifyObservers(null);????}????public?void?notifyObservers(Object?arg)?{????????Object[]?arrLocal;????????synchronized?(this)?{????????????if?(!changed)????????????????return;????????????arrLocal?=?obs.toArray();????????????clearChanged();????????}????????for?(int?i?=?arrLocal.length-1;?i>=0;?i--)????????????((Observer)arrLocal[i]).update(this,?arg);????}????public?synchronized?void?deleteObservers()?{????????obs.removeAllElements();????}????protected?synchronized?void?setChanged()?{????????changed?=?true;????}????protected?synchronized?void?clearChanged()?{????????changed?=?false;????}????public?synchronized?boolean?hasChanged()?{????????return?changed;????}????public?synchronized?int?countObservers()?{????????return?obs.size();????}}(五)总结观察者模式在不同的场景下还有不同的叫法,比如在本文的例子中,观察者模式叫做发布-订阅(publish-Subscribe)模式会更合适;观察者模式还可以叫做源-监听器(Source-Listener)模式,但是不管怎么叫,它的定义都是相同的。