zoukankan      html  css  js  c++  java
  • 观察者模式:探索消息推送与注册中心

    一、引入话题-发散思考

    1、如果你是安卓开发工程师,是否经常遇到给所有的用户或者特定的用户推送消息的业务场景呢?例如:我曾经做的一款APP就是用极光推送一个消息,下载该APP的用户都能收到消息提示。
     
    2、如果你了解zookeeper分布式调节框架?假设一个集群有1000台机器Master-Slave结构,我想给这个集群修改配置文件,都是一模一样的文件在不同机器上,难道我们一台一台机器修改?答案是当然不能。那怎么解决?那配置文件注册到zookeeper上,然后集群机器监听配置文件的变化,当配置文件改变以后,观察者就能知道,并且对配置文件作出对应的配置。如果兴趣想详细了解看我zookeeper文章介绍。

    二、简介

    观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会接受到通知并且自动更新。
     
    应用场景:
    • 消息推送(广播)
    • 注册中心/消息订阅
    场景描述:
         假设观察者们都是电灯泡,当他们的state为1的时候,所有的电灯泡都点亮,如果state为0的时候,所有的电灯泡都熄灭。那么假设有一个电灯泡注册中心,也就是总开关,所有的电灯泡的控制权都需在电灯泡注册中心手上,当注册中心设置灯泡的开关为1的时候,所有的电灯泡都会收到一个消息,那么就会根据消息数据做出相应的反应。

     

    二、自定义接口实现

    //主题接口
    public interface Subject {
         void registerObserver(Observer observer);
         void removeObject(Observer observer);
         void notifyObservers();
    }
    

    //主题具体实现类
    public class ConcreteSubject implements Subject{

     List</span>&lt;Observer&gt; observers=<span style="color: #0000ff;">new</span> ArrayList&lt;Observer&gt;<span style="color: #000000;">();
     </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> state;
    
     </span><span style="color: #008000;">//</span><span style="color: #008000;">注册观察者 </span>
    

    @Override
    public void registerObserver(Observer observer) {
    observers.add(observer);
    }

     </span><span style="color: #008000;">//</span><span style="color: #008000;">移除观察者</span>
    

    @Override
    public void removeObject(Observer observer) {
    int index=observers.indexOf(observer);
    if(index>=0){
    observers.remove(index);
    return;
    }
    }

     </span><span style="color: #008000;">//</span><span style="color: #008000;">通知观察者:类似消息推送</span>
    

    @Override
    public void notifyObservers() {
    for(Observer observer:observers){
    observer.update(
    this);
    }
    }

     </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> getState() {
           </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> state;
     }
    
     </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> setState(<span style="color: #0000ff;">int</span><span style="color: #000000;"> state) {
           </span><span style="color: #0000ff;">this</span>.state =<span style="color: #000000;"> state;
           notifyObservers();
     }
    

    }

    //观察者接口
    public interface Observer {
    void update(Subject subject);
    }

    //观察者实现类
    public class ConcreteObserver implements Observer{

     </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> state;
     
     </span><span style="color: #008000;">//</span><span style="color: #008000;">同步主题的状态</span>
    

    @Override
    public void update(Subject subject) {
    this.state=((ConcreteSubject)subject).getState();
    }

     </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> getState() {
           </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> state;
     }
    
     </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> setState(<span style="color: #0000ff;">int</span><span style="color: #000000;"> state) {
           </span><span style="color: #0000ff;">this</span>.state =<span style="color: #000000;"> state;
     }
    

    }

    //客户端测试类
    public class Client {
    public static void main(String[] args) {
    Subject subject
    =new ConcreteSubject();

           ConcreteObserver observerA</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> ConcreteObserver();
           ConcreteObserver observerB</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> ConcreteObserver();
    
           subject.registerObserver(observerA);
           subject.registerObserver(observerB);
    
           ((ConcreteSubject)subject).setState(</span>10<span style="color: #000000;">);
           System.out.println(</span>"观察者A(订阅者A):"+<span style="color: #000000;">observerA.getState());
           System.out.println(</span>"观察者B(订阅者B):"+<span style="color: #000000;">observerB.getState());
     }
    

    }

    运行结果:
    观察者A(订阅者A):10
    观察者B(订阅者B):
    10

    三、Java提供API

    //具体主题类(继承自主题类Observable)
    public class ConcreteSubject extends Observable{
        private int state;
        public void setState(int state) {
            this.state = state;
            setChanged();
            notifyObservers();
        }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> getState() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> state;
    }
    

    }

    //具体观察者(实现javaAPI Observer)
    public class ConcreteObserver implements Observer{
    private int state;
    @Override
    public void update(Observable o, Object arg) {
    this.state=((ConcreteSubject)o).getState();
    }

     </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> getState() {
           </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> state;
     }
    

    }

    //客户端
    public class Client {
    public static void main(String[] args) {
    ConcreteSubject subject
    =new ConcreteSubject();

           ConcreteObserver observerA</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> ConcreteObserver();
           ConcreteObserver observerB</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> ConcreteObserver();
    
           subject.addObserver(observerA);
           subject.addObserver(observerB);
           subject.setState(</span>123<span style="color: #000000;">);
    
           System.out.println(</span>"观察者A(订阅者A):"+<span style="color: #000000;">observerA.getState());
           System.out.println(</span>"观察者B(订阅者B):"+<span style="color: #000000;">observerB.getState());
     }
    

    }

    运行结构:
    观察者A(订阅者A):123
    观察者B(订阅者B):
    123

    四、版权声明

      作者:邱勇Aaron

      出处:http://www.cnblogs.com/qiuyong/

      您的支持是对博主深入思考总结的最大鼓励。

      本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,尊重作者的劳动成果。

      参考:Head First 设计模式

  • 相关阅读:
    udev 禁止某些驱动自动加载
    AT91SAM9XEK ramdisk 启动笔记
    MTD 工具使用
    kmp问题
    野指针 空指针 通用指针
    manacher算法实现
    manacher算法
    strcpy和strlen
    冒泡排序
    C++的重载(overload)与重写(override
  • 原文地址:https://www.cnblogs.com/qiuyong/p/7079973.html
Copyright © 2011-2022 走看看