首页 > 编程 > Java > 正文

Java设计模式开发中使用观察者模式的实例教程

2019-11-26 14:25:31
字体:
来源:转载
供稿:网友

观察者模式是软件设计模式中的一种,使用也比较普遍,尤其是在GUI编程中。关于设计模式的文章,网络上写的都比较多,而且很多文章写的也不错,虽然说有一种重复早轮子的嫌疑,但此轮子非彼轮子,侧重点不同,思路也不同,讲述方式也不近相同。
关键要素

主题:

主题是观察者观察的对象,一个主题必须具备下面三个特征。

  • 持有监听的观察者的引用
  • 支持增加和删除观察者
  • 主题状态改变,通知观察者

观察者:

当主题发生变化,收到通知进行具体的处理是观察者必须具备的特征。

为什么要用这种模式

这里举一个例子来说明,牛奶送奶站就是主题,订奶客户为监听者,客户从送奶站订阅牛奶后,会每天收到牛奶。如果客户不想订阅了,可以取消,以后就不会收到牛奶。

松耦合

观察者增加或删除无需修改主题的代码,只需调用主题对应的增加或者删除的方法即可。
主题只负责通知观察者,但无需了解观察者如何处理通知。举个例子,送奶站只负责送递牛奶,不关心客户是喝掉还是洗脸。
观察者只需等待主题通知,无需观察主题相关的细节。还是那个例子,客户只需关心送奶站送到牛奶,不关心牛奶由哪个快递人员,使用何种交通工具送达。

Java实现观察者模式
1. Java自带的实现
类图

201642494900291.jpg (806×524)

/**  * 观察目标 继承自 java.util.Observable  * @author stone  *  */ public class UpdateObservable extends Observable {      private int data;      public UpdateObservable(Observer observer) {     addObserver(observer);     /*      * add other observer      */   }      public int getData() {     return data;   }      public void setData(int data) {     if (data != this.data) {       this.data = data;       setChanged(); //标记 改变, 只有标记后才能通知到       notifyObservers(); //通知     }        }    @Override   public synchronized void addObserver(Observer o) {     super.addObserver(o);   }    @Override   public synchronized void deleteObserver(Observer o) {     super.deleteObserver(o);   }    @Override   public void notifyObservers() {     super.notifyObservers();   }    @Override   public void notifyObservers(Object arg) {     super.notifyObservers(arg);   }    @Override   public synchronized void deleteObservers() {     super.deleteObservers();   }    @Override   protected synchronized void setChanged() {     super.setChanged();   }    @Override   protected synchronized void clearChanged() {     super.clearChanged();   }    @Override   public synchronized boolean hasChanged() {     return super.hasChanged();   }    @Override   public synchronized int countObservers() {     return super.countObservers();   }    } 
/**  * 观察者 实现 java.util.Observer接口  * @author stone  *  */ public class UpdateObserver implements Observer {    @Override   public void update(Observable o, Object arg) {     System.out.println("接收到数据变化的通知:");     if (o instanceof UpdateObservable) {       UpdateObservable uo = (UpdateObservable) o;       System.out.print("数据变更为:" + uo.getData());     }   }  } 

2. 自定义的观察模型
类图

201642494952492.jpg (968×676)

/**  * 抽象观察者  Observer  * 观察 更新      * @author stone  *  */ public interface IWatcher {   /*    * 通知接口:    * 1. 简单通知    * 2. 观察者需要目标的变化的数据,那么可以将目标用作参数, 见Java的Observer和Observable    */ // void update(IWatched watched);      void update();    } 
/**  * 抽象目标 Subject  * 提供注册和删除观察者对象的接口, 及通知观察者进行观察的接口  * 及目标 自身被观察的业务的接口  * @author stone  *  */ public interface IWatchedSubject {      public void add(IWatcher watch);    public void remove(IWatcher watch);      public void notifyWhatchers();      public void update();//被观察业务变化的接口 } 
/**  * 具体观察者    Concrete Observer  *  * @author stone  *  */ public class UpdateWatcher implements IWatcher {    @Override   public void update() {     System.out.println(this + "观察到:目标已经更新了");   }  } 


/**  * 具体目标角色  Concrete Subject  * @author stone  *  */ public class UpdateWatchedSubject implements IWatchedSubject {   private List<IWatcher> list;      public UpdateWatchedSubject() {     this.list = new ArrayList<IWatcher>();   }      @Override   public void add(IWatcher watch) {     this.list.add(watch);   }    @Override   public void remove(IWatcher watch) {     this.list.remove(watch);   }    @Override   public void notifyWhatchers() {     for (IWatcher watcher : list) {       watcher.update();     }   }      @Override   public void update() {     System.out.println("目标更新中....");     notifyWhatchers();   }  } 


监听器是观察者的一种实现:
类图

201642495137152.jpg (780×502)

/**  * 监听 用户在注册后  * @author stone  *  */ public interface IRegisterListener {   void onRegistered(); } 
/**  * 监听 当用户登录后  * @author stone  *  */ public interface ILoginListener {   void onLogined(); } 
/*  * 监听器 是观察者模式的一种实现  * 一些需要监听的业务接口上添加 监听器,调用监听器的相应方法,实现监听  */ public class User {      public void register(IRegisterListener register) {     /*      * do ... register      */     System.out.println("正在注册中...");     //注册后     register.onRegistered();   }    public void login(ILoginListener login) {     /*      * do ... login      */     System.out.println("正在登录中...");     //登录后     login.onLogined();   }  } 


/**  * 观察者(Observer)模式 行为型模式  *  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时观察某一个目标对象。  *  这个目标对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己  * 目标对象中需要有添加、移除、通知 观察者的接口  *   * @author stone  */ public class Test {      public static void main(String[] args) {     /*      * 使用Java自带的Observer接口和Observable类      */     UpdateObservable observable = new UpdateObservable(new UpdateObserver());     observable.setData(99);     System.out.println("");     System.out.println("");     /*      * 自定义的观察者模型      */     IWatchedSubject watched = new UpdateWatchedSubject();     watched.add(new UpdateWatcher());     watched.add(new UpdateWatcher());     watched.update();     System.out.println("");          /*      * 子模式-监听器      */          User user = new User();     user.register(new IRegisterListener() {              @Override       public void onRegistered() {         System.out.println("监听到注册后。。。");       }     });     user.login(new ILoginListener() {              @Override       public void onLogined() {         System.out.println("监听到登录后。。。");       }     });        } } 


打印

接收到数据变化的通知: 数据变更为:99  目标更新中.... observer.UpdateWatcher@457471e0观察到:目标已经更新了 observer.UpdateWatcher@5fe04cbf观察到:目标已经更新了  正在注册中... 监听到注册后。。。 正在登录中... 监听到登录后。。。 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表