zoukankan      html  css  js  c++  java
  • 观察者模式(Observer)

          观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并更新。

    主题和观察者定义了一对多的关系,观察者依赖于主题。当主题对象的状态发生改变时,观察者就会被通知。根据通知观察者进行相关操作。

     一、 涉及角色主题接口观察者接口具体主题具体观察者。

         

        

    优点:主题是真正拥有数据的对象,观察者是主题的依赖者,在数据变化跟新时这样比多个对象控制同一份数据,可以更干净的OO设计。

    缺点:并不是所有的观察者都需要这份数据,有可能只需要其中的一部分,却接收了一堆数据。(JDK中的观察这模式,提供了支持,支持以个getter方法的主动获取数据)

    二、代码实例

         (1)抽象观察者角色

    1 public interface Observer {
    2     /**
    3      * <p>观察者对象更新自己的信息</p>
    4      * @author maxianming 2016-1-11 下午2:11:44
    5      * @param Message
    6      */
    7     public void update(String Message);
    8 }

         (2)抽象主题角色

      

     1 public interface Subject {
     2     /**
     3      * <p>主题对象中注册一个观察者</p>
     4      * @author maxianming 2016-1-11 下午2:09:17
     5      * @param observer
     6      */
     7     public void registerObserver(Observer observer);
     8     /**
     9      * <p>主题对象中删除一个观察者</p>
    10      * @author maxianming 2016-1-11 下午2:09:53
    11      * @param observer
    12      */
    13     public void removeObserver(Observer observer);
    14     /**
    15      * <p>主题对象改变通知所有的观察者对象</p>
    16      * @author maxianming 2016-1-11 下午2:11:05
    17      */
    18     public void notifyObservers();
    19 }

         (3)具体观察者角色

     1 public class ConcreteObserver implements Observer {
     2     private Subject subject;
     3     
     4     public ConcreteObserver(Subject subject){
     5         this.subject = subject;
     6         subject.registerObserver(this);
     7     }
     8     
     9     @Override
    10     public void update(String message) {
    11          System.out.println("具体观察者得到 【主题对象的信息】为:" + message);        
    12     }
    13     
    14 }

         (4)具体主题角色

     1 public class ConcreteSubject implements Subject {
     2     private ArrayList<Observer> observers;
     3     private String message;
     4     
     5     public ConcreteSubject(){
     6         this.observers = new ArrayList<Observer>();
     7     }
     8     @Override
     9     public void registerObserver(Observer observer) {
    10         this.observers.add(observer);
    11     }
    12     
    13     @Override
    14     public void removeObserver(Observer observer) {
    15         boolean hasObserver = this.observers.contains(observer);
    16         if(hasObserver){
    17             this.observers.remove(observer);
    18         }
    19     }
    20     
    21     @Override
    22     public void notifyObservers() {
    23         for (int i = 0; i < observers.size(); i++) {
    24             Observer observer = observers.get(i);
    25             if(observer != null){
    26                 observer.update(this.message);
    27             }
    28             
    29         }
    30     }
    31     
    32     public void setData(String message){
    33         this.message = message;
    34         //状态改变,通知观察者
    35         this.notifyObservers();
    36     }
    37 }

         (5)客户端

     1 public class Client {
     2     public static void main(String[] args) {
     3         //1、主题对象
     4         ConcreteSubject subject = new ConcreteSubject();
     5         //2、观察者对象
     6         Observer observer = new ConcreteObserver(subject);
     7         //3、主题对象信息改变
     8         subject.setData("213123213");
     9         
    10         //4、删除观察者对象
    11         subject.removeObserver(observer);
    12         //5、主题对象信息gaibian
    13         subject.setData("3456178");
    14     }
    15 }

    三、JDK中观察者模式

        JDK对观察者模式提供了支持。主题类Observable,具体主题类可以继承JDK中实现类Observable类。具体观察者可以实现JDK中的观察者接口Observer接口

        主题通知观察者:继承JDKObservable的主题接口,通知观察者对象步骤。

        (1)先调用Observable中的setChanged()方法。标记状态已经改变

        (2)再调用notifyObservers()或notifyObservers(arg)(带参数方法可以推送指定的参数)。

        

  • 相关阅读:
    SpringCloud笔记(一)服务注册与发现
    个人备忘录
    ActiveMQ 消息持久化到Mysql数据库
    染色 [组合数 容斥]
    各种图床
    NOIP2012 疫情控制
    网格计数
    找钱 [多重背包 计数]
    序列[势能线段树]
    牛客挑战赛33 B-鸽天的放鸽序列
  • 原文地址:https://www.cnblogs.com/mxmbk/p/5083464.html
Copyright © 2011-2022 走看看