zoukankan      html  css  js  c++  java
  • Android设计模式之观察者模式

    上一篇讲述了单例模式,简单,理解起来也不会太困难,接下来继续讲一下观察者模式

    观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己

    看定义,依然会有点懵逼,待会还是看实际代码吧。。。

    观察者模式的特点:

    1.它实现了 Subject 和 Observer 之间的松耦合,Subject只知道观察者实现了 Observer 接口,主题不需要知道具体的类是谁、做了些什么或其他任何细节。

    2.任何时候我们都可以增加新的观察者。

    3.因为主题唯一依赖的东西是一个实现Observer 接口的对象列表,所以我们可以随时增加观察者,同样的,也可以在任何时候删除观察者,当然更不用去关心观察者的类型,只要实现了Observer接口即可,Subject 最后只会发通知给实现了 Observer 接口的观察者。

    4.Subject 和 Observer 之间实现松耦合之后,双方代码的修改都不会影响到另外一方,当然前提是双方得遵守接口的规范。

    适用环境:

    1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
    2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
    3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
     
    下面,通过代码来深入理解吧,
    观察者模式实现主要分四步:
    第一步:创建目标
    第二步:创建观察者
    第三步:注册观察者
    第四步:订阅目标信息发生改变或更新
     
    简略看一下类图:

     首先第一个,创建一个目标父类Subject

     1 /*
     2 * 创  建  者: ouyangshengduo
     3 * 创建时间: 2017年3月31日
     4 * 文件名称: Subject.java
     5 * 版权信息: 2017 Edan. All rights reserved. 
     6 * 文件描述: 观察者模式中的目标父类,管理观察者
     7 */
     8 package com.oysd.model.observer;
     9 
    10 import java.util.ArrayList;
    11 import java.util.List;
    12 
    13 public class Subject {
    14     
    15     /**
    16      * 声明并初始化管理观察者的集合
    17      */
    18     private List<Observer> observers = new ArrayList<Observer>();
    19     
    20     
    21     /**
    22      * 注册观察者方法
    23      * @param observer
    24      */
    25     public void attach(Observer observer){
    26         observers.add(observer);
    27     }
    28     
    29     /**
    30      * 移除特定的观察者
    31      * @param observer
    32      */
    33     public void detach(Observer observer){
    34         observers.remove(observer);
    35     }
    36     
    37     /**
    38      * 通知所有注册的观察者
    39      */
    40     public void notifyObserver(){
    41         for(Observer observer : observers){
    42             observer.update(this);
    43         }
    44     }
    45     
    46     
    47 
    48 }

    创建观察者的接口Observer

     1 /*
     2 * 创  建  者: ouyangshengduo
     3 * 创建时间: 2017年3月31日
     4 * 文件名称: Observer.java
     5 * 版权信息: 2017 Edan. All rights reserved. 
     6 * 文件描述: 观察者接口
     7 */
     8 package com.oysd.model.observer;
     9 
    10 public interface Observer {
    11 
    12     /**
    13      * 订阅信息更新通知
    14      * @param subject
    15      */
    16     public void update(Subject subject);
    17 }

    创建具体目标对象ConcreteSubject

     1 /*
     2 * 创  建  者: ouyangshengduo
     3 * 创建时间: 2017年3月31日
     4 * 文件名称: ConcreteSubject.java
     5 * 版权信息: 2017 Edan. All rights reserved. 
     6 * 文件描述: 具体的目标类
     7 */
     8 package com.oysd.model.observer;
     9 
    10 public class ConcreteSubject extends Subject {
    11     
    12     //订阅信息
    13     private String notifyInfo;
    14 
    15     public String getNotifyInfo() {
    16         return notifyInfo;
    17     }
    18 
    19     
    20     //订阅信息的更改
    21     public void setNotifyInfo(String notifyInfo) {
    22         this.notifyInfo = notifyInfo;
    23         
    24         this.notifyObserver();
    25     }
    26     
    27     
    28 
    29 }

    创建具体的观察者对象ConcreteObserver

     1 /*
     2 * 创  建  者: ouyangshengduo
     3 * 创建时间: 2017年3月31日
     4 * 文件名称: ConcreteObserver.java
     5 * 版权信息: 2017 Edan. All rights reserved. 
     6 * 文件描述: 具体的观察者对象
     7 */
     8 package com.oysd.model.observer;
     9 
    10 public class ConcreteObserver implements Observer {
    11     //观察者名字
    12     private String observerName;
    13     
    14     //观察者订阅信息
    15     private String notifyInfo;
    16     
    17     //观察者处理信息
    18     private String excuteInfo;
    19     
    20 
    21     @Override
    22     public void update(Subject subject) {
    23         // TODO Auto-generated method stub
    24 
    25         notifyInfo = ((ConcreteSubject) subject).getNotifyInfo();
    26         System.out.println(observerName + "收到" + notifyInfo + "," + excuteInfo);
    27 
    28     }
    29 
    30 
    31     public String getObserverName() {
    32         return observerName;
    33     }
    34 
    35 
    36     public void setObserverName(String observerName) {
    37         this.observerName = observerName;
    38     }
    39 
    40 
    41     public String getNotifyInfo() {
    42         return notifyInfo;
    43     }
    44 
    45 
    46     public void setNotifyInfo(String notifyInfo) {
    47         this.notifyInfo = notifyInfo;
    48     }
    49 
    50 
    51     public String getExcuteInfo() {
    52         return excuteInfo;
    53     }
    54 
    55 
    56     public void setExcuteInfo(String excuteInfo) {
    57         this.excuteInfo = excuteInfo;
    58     }
    59     
    60     
    61 
    62 }

    新建一个测试类Client

     1 /*
     2 * 创  建  者: ouyangshengduo
     3 * 创建时间: 2017年3月31日
     4 * 文件名称: Client.java
     5 * 版权信息: 2017 Edan. All rights reserved. 
     6 * 文件描述: 
     7 */
     8 package com.oysd.model.observer;
     9 
    10 public class Client {
    11 
    12     public static void main(String[] args) {
    13         // TODO Auto-generated method stub
    14 
    15         
    16         //第一步:创建目标实例
    17         ConcreteSubject subject = new ConcreteSubject();
    18         
    19         //第二步:创建观察者实例
    20         ConcreteObserver observer1 = new ConcreteObserver();
    21         observer1.setObserverName("observer1");
    22         observer1.setExcuteInfo("observer1处理信息");
    23         
    24         ConcreteObserver observer2 = new ConcreteObserver();
    25         observer2.setObserverName("observer2");
    26         observer2.setExcuteInfo("observer2处理信息");
    27         
    28         //第三步:注册观察者
    29         subject.attach(observer1);
    30         subject.attach(observer2);
    31         
    32         //第四步:订阅信息发生更改或更新
    33         subject.setNotifyInfo("订阅信息发生更改");
    34     }
    35 
    36 }

    运行结果:

    1 observer1收到订阅信息发生更改,observer1 处理信息
    2 observer2收到订阅信息发生更改,observer2处理信息

    综上,观察者模式的通用写法就写完了

    观察者模式又分推/拉模式,通用写法是拉模式

    所谓拉模式就是目标类不知道观察者想要什么信息,就整个都获取,然后想要什么 就拿什么,

    observer.update(this);就是把这个对象都返回

    而推模式,就是目标类知道观察者想要什么信息,就直接发送特定的信息,那么就更改传入参数,就可以由拉模式改成推模式

    observer.update(para);

    引入观察者模式的时候,使用者要充分考虑运行环境后,实际情况实际分析,也不能盲目使用。

  • 相关阅读:
    zmap zgrab 环境搭建
    RF是如何工作的?
    RF的优缺点
    国内NLP的那些人那些会
    B-、B+、B*树
    关于LDA的gibbs采样,为什么可以获得正确的样本?
    LDA算法里面Dirichlet分布的两个参数alpha和beta怎样确定?
    如何确定LDA的主题个数
    SMO算法精解
    奇异值与主成分分析(PCA)
  • 原文地址:https://www.cnblogs.com/ouyangduoduo/p/6652517.html
Copyright © 2011-2022 走看看