java观察者模式学习总结

来源:互联网 发布:学校网络拓扑图图片 编辑:程序博客网 时间:2024/05/16 08:27


观察者模式在Java语言中的地位极其重要,JDK也提供了对观察者模式的内置支持,实现思路是:Observable类用于创建主题类,当这种子类的对象发生变化时,观测类被通知,观测类必须实现定义了update()方法的Observer接口。 当一个观测程序被通知到一个被观测对象的改变时,update()方法被调用。

下面学习到自己搭建观察者模式的步骤:

1、创建两个接口,一个是抽象的主题角色(被观察的对象),一个是抽象的观察者角色。

package observer;/* * 抽象的主题角色 */public interface Watched{//这里Watcher是一个接口public void addWathcer(Watcher watcher);public void removeWatcher(Watcher watcher);public void notifyWatchers(String str);}


package observer;/* * 抽象的观察者角色 */public interface Watcher{public void update(String str);}


2、创建两个角色的实现类

package observer;import java.util.ArrayList;import java.util.List;public class ConcreteWatched implements Watched{//创建一个集合,用来承载观察自己的观察者们private List<Watcher> list = new ArrayList<Watcher>();@Overridepublic void addWathcer(Watcher watcher){list.add(watcher);}@Overridepublic void removeWatcher(Watcher watcher){list.remove(watcher);}//主题对象在此处调用观察者对象,在AWT中是在内部实现,外部看不到,会误以为是自动调用,其实是由主题调用@Overridepublic void notifyWatchers(String str){for(Watcher watcher : list){watcher.update(str);}}}

package observer;public class ConcreteWatcher implements Watcher{@Overridepublic void update(String str){System.out.println(str);}}


3、创建测试类,实现观察者模式

package observer;public class test{public static void main(String[] args){/* * 对应到AWT模型中,观察者模式就容易理解了 *///相当于按钮Watched origin = new ConcreteWatched();Watcher watcher1 = new ConcreteWatcher();Watcher watcher2 = new ConcreteWatcher();Watcher watcher3 = new ConcreteWatcher();//相当于添加监听器origin.addWathcer(watcher1);origin.addWathcer(watcher2);origin.addWathcer(watcher3);//相当于点击按钮origin.notifyWatchers("First notity");origin.removeWatcher(watcher3);origin.notifyWatchers("Second notify");}}


在学习过程中,对观察者模式的理解,最重要的在于第2步中主题对象调用观察者对象,通过遍历所有观察者,实现观察者中的方法。其次还有主题中使用集合建立与观察者之间的关联。

由于观察者模式在AWT,swing中使用很广泛,学习观察者模式有助于swing中按钮添加监听事件的原理,并不是自动实现方法调用,而是作为主题的按钮实现了对事件的调用。

通过练习观察者模式,进一步体会到了接口的作用(因为单纯的看这个例子不禁会想到-为什么明明可以用类直接实现的,还要多设计两个接口,接口(抽象主题、观察者角色)在这里的作用是什么?):

原由:在创建主题类和观察者类时,完全可以不使用接口,如下:

ConcreteWatched origin = new ConcreteWatched();ConcreteWatcher watcher1 = new ConcreteWatcher();ConcreteWatcher watcher2 = new ConcreteWatcher();ConcreteWatcher watcher3 = new ConcreteWatcher();

解释:  
  此处也是多态的使用,在这个例子中只对Watched和Watcher接口实现了一种类,没有体现出使用接口的优势
  如果有多个方法相同的类而不使用接口,创建不同主题角色,就要改变一次其参数类型,看上去很混乱
  如: ConcreteWatched1:public void addWathcer(ConcreteWatcher1 watcher){}
     ConcreteWatched2:public void addWathcer(ConcreteWatcher2 watcher){}
  而利用接口抽象出来后,主题角色的参数类型用接口表示就无需改变其参数类型,只需实现本身的功能就可以
     ConcreteWatched1:public void addWathcer(Watcher watcher){}
     ConcreteWatched2:public void addWathcer(Watcher watcher){}
  说到底,就是接口在java中的作用:
  达到统一访问,就是在创建对象的时候用接口创建,
  【接口名】【对象名】 = new 【实现接口的类】,
  这样用哪个类的对象就可以new哪个对象了,不需要改原来的代码。
  主要体现在多个类实现同一个接口时,统一访问的优势才会发挥出来
  而且,在使用时,多态的使用使代码更整齐易懂


0 0
原创粉丝点击