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

    观察者模式原理

      当一个对象改变了自身的状态后,它会通知其他对象告知发生了变化。
      用设计模式的语言来说,改变自身状态的对象叫做主题(Subject),接受改变通知的那些对象叫做观察者。其关系是一对多的,一个主题可以有多个观察者。

    观察者类图

      观察者模式引入了一个Observer接口,所有具体的观察者都需要实现该接口。该接口只有一个方法,主题会调用该方法,通知观察者自己的状态发生了变化。每个主题都持有一个已注册的观察者列表,并且会调用一个方法(notifyObservers)来通知注册的观察者关于主题的更新或是变化。主题提供了注册和取消注册观察者的方法。

    使用普通方法实现观察者模式

      Java对观察者模式提供了开箱即用的实现。通过实现Observer接口,以及继承Observable类,可以轻松实现观察者模式。

      用观察者模式做一个新闻订阅的功能,当新闻发生改变的时候,通知所有订阅者有新的新闻。

      定义主题:

     1 import java.util.ArrayList;
     2 import java.util.List;
     3 import java.util.Observable;
     4 import java.util.Observer;
     5 
     6 /**
     7  * @author jiashubing
     8  * @since 2017/7/17
     9  */
    10 public class NewsAgency extends Observable implements Publisher {
    11     private List<Observer> channels = new ArrayList<>();
    12 
    13     public void addNews(String newsItem){
    14         notifyObservers(newsItem);
    15     }
    16 
    17     public void notifyObservers(String newsItem){
    18         for(Observer outlet : this.channels){
    19             outlet.update(this, newsItem);
    20         }
    21     }
    22 
    23     public void register(Observer outlet){
    24         channels.add(outlet);
    25     }
    26 }

       Publisher接口:

    public interface Publisher {
    }

       具体的观察者:

     1 import java.util.Observable;
     2 import java.util.Observer;
     3 
     4 /**
     5  * @author jiashubing
     6  * @since 2017/7/17
     7  */
     8 public class RadioChannel implements Observer {
     9 
    10     @Override
    11     public void update(Observable agency, Object newsItem){
    12         if(agency instanceof Publisher){
    13             System.out.println((String)newsItem);
    14         }
    15     }
    16 }

       测试:

     1 public class Test {
     2     public static void main(String[] args){
     3         //创建主题
     4         NewsAgency newsAgency = new NewsAgency();
     5 
     6         //创建观察者
     7         RadioChannel radioChannel1 = new RadioChannel();
     8         RadioChannel radioChannel2 = new RadioChannel();
     9 
    10         //主题注册观察者
    11         newsAgency.register(radioChannel1);
    12         newsAgency.register(radioChannel2);
    13 
    14         newsAgency.addNews("第一条新闻");
    15         newsAgency.addNews("第二条新闻");
    16         newsAgency.addNews("第三条新闻");
    17     }
    18 }

       输出结果为:

    第一条新闻
    第一条新闻
    第二条新闻
    第二条新闻
    第三条新闻
    第三条新闻

       其中Observer 接口的内容是:

    public interface Observer {
        void update(Observable o, Object arg);
    }

       Observable类的代码就比较多了。

      参考《Professional Java EE Design Patterns》


      原创文章,欢迎转载,转载请注明出处!

  • 相关阅读:
    redis的其他命令
    redis的有序集合ZSET(stored set)
    redis 的set数据类型
    redis 的hash数据类型
    php命令
    intellij idea
    生产者消费者问题
    JAVA sleep和wait 异同
    JAVA线程通信
    java线程同步--lock锁(JDK 5 新增)
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/observer.html
Copyright © 2011-2022 走看看