• 阅读《Design pattern》-观察者模式


    摘抄《设计模式》

    意图:
    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
    别名:
    依赖(dependent),发布-订阅(publish-subscribe)
    适用性:
    在以下情况下可以使用观察者模式:
    一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中,以使它们可以各自独立地改变和复用。
    对一个对象的改变需要同时改变其他对象,而不知道具体由多少对象需要改变。
    一个对象必须通知其他对象,而他又不能假定其他对象是谁。换言之,你不希望这些对象紧密耦合的。
     
    简单一句话:目标状态变化,触发所有观察者变化。
    注意:一对多的关系,一个目标,多个观察者
     
    目标提供一个方法:用于附上观察者,便于notify(通知)
    观察者在初始时,关注(订阅)目标,并附上在目标上。释放时,取消关注(订阅),移除。
     

    建立一个简单的观察者代码:
     1 /**
     2  * 观察者模式-目标接口
     3  */
     4 public interface ISubject {
     5     /**
     6      * 附上观察者
     7      * @param observer 观察者
     8      */
     9     public void attach(IObserver observer);
    10 
    11     /**
    12      * 移除观察者
    13      * @param observer 观察者
    14      */
    15     public void detach(IObserver observer);
    16 
    17     /**
    18      * 通知所有观察者
    19      */
    20     public void notifyAllObserver();
    21 }
     1 /**
     2  * 观察者模式-观察者接口
     3  */
     4 public interface IObserver {
     5     /**
     6      * 订阅目标
     7      * @param subject 目标
     8      */
     9     public void subscribe(ISubject subject);
    10 
    11     /**
    12      * 取消订阅
    13      */
    14     public void unsubscribe();
    15 
    16     /**
    17      * 业务更新
    18      * @param subject 目标
    19      */
    20     public void update(ISubject subject);
    21 }

    上述是接口。下面定义父类基类

     1 /**
     2  * 目标基类/父类
     3  */
     4 public class BaseSubject implements ISubject {
     5     /**
     6      * 观察者列表
     7      */
     8     protected List<IObserver> observerList;
     9 
    10     /**
    11      * 构造函数
    12      */
    13     public BaseSubject() {
    14         observerList = new ArrayList<>();
    15     }
    16 
    17     @Override
    18     public void attach(IObserver observer) {
    19         if (observer != null) {
    20             observerList.add(observer);
    21         }
    22     }
    23 
    24     @Override
    25     public void detach(IObserver observer) {
    26         if (observer != null) {
    27             observerList.remove(observer);
    28         }
    29     }
    30 
    31     @Override
    32     public void notifyAllObserver() {
    33         for (IObserver item :
    34                 observerList) {
    35             item.update(this);
    36         }
    37     }
    38 
    39     @Override
    40     protected void finalize() throws Throwable {
    41         for (IObserver item :
    42                 observerList) {
    43             item.unsubscribe();
    44         }
    45         observerList.clear();
    46         super.finalize();
    47     }
    48 }
     1 /**
     2  * 观察者基类/父类
     3  */
     4 public class BaseObserver implements IObserver {
     5     /**
     6      * 目标对象
     7      */
     8     protected ISubject subject;
     9 
    10     /**
    11      * 构造函数
    12      */
    13     public BaseObserver() {
    14         this.subject = null;
    15     }
    16 
    17     /**
    18      * 构造函数
    19      * @param subject 目标
    20      */
    21     public BaseObserver(ISubject subject) {
    22         this.subject = null;
    23         subscribe(subject);
    24     }
    25 
    26     @Override
    27     public void subscribe(ISubject subject) {
    28         if (subject != null) {
    29             this.subject = subject;
    30         }
    31         if (this.subject != null) {
    32             this.subject.attach(this);
    33         }
    34     }
    35 
    36     @Override
    37     public void unsubscribe() {
    38         if (this.subject != null) {
    39             this.subject.detach(this);
    40         }
    41     }
    42 
    43     @Override
    44     public void update(ISubject subject) {
    45         if (subject == this.subject) {
    46             // 自己的业务
    47         }
    48     }
    49 
    50     @Override
    51     protected void finalize() throws Throwable {
    52         unsubscribe();
    53         this.subject = null;
    54         super.finalize();
    55     }
    56 }

    上述是基类/父类,后续再继承各自的父类,进行实际业务的开展。

    【实际业务的代码以及测试,这里不写了】

     
     
    特别说明:
    在不考虑效率的情况下,上述代码可以了。
    但更多的时候,更多业务和资源,不允许不限制使用。
     
    说简单点,在上述的情况下,需要做一个资源优化(比如,重复刷新、频繁刷新、占用资源过多如何处理、推或拉的效率问题)。这个取决于业务本身。
    再比如:
    1、需要观察多个目标,是观察者模式1对多关系的升级扩展
    2、更新协议-推拉模型的选定或混用
    3、封装复杂的更新语义

  • 相关阅读:
    整数幂的求解
    非递归实现不重复序列的全排列(二)
    完整的将日期时间转换为汉字的代码
    如何得到某集合的所有子集合?
    再谈八皇后问题
    大数阶乘的计算(六)
    非递归实现不重复序列的全排列(一)
    非递归实现不重复序列的全排列(三)
    大数阶乘的计算(五)
    关于走楼梯的递归算法
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/13637858.html
Copyright © 2020-2023  润新知