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

    第一、观察者模式定义

    观察者模式(ObServer Pattern)定义对象之间的一对多的依赖,让多个观察者对象同时监听一个对象,当主体对象发生变化时,它的所有依赖者(观察者)

    都会收到通知并更新,其实就是发布定义模式,发布者发布消息,订阅者获取消息,订阅了就能接收到消息,没有订阅就接收不到消息。

    第二、观察者模式应用场景

    Zookeeper事件通知节点、消息订阅通知、安卓开发事件注册分布式配置中心

    第三、观察者模式原理类图

    抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,

    可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

    抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

    具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。

    具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态

    第四、观察者模式简单实现

    /**
     * 抽象主题
     */
    public interface AbstractSubject {
        /**
         * 添加ObServer 添加订阅者
         * @param obServer
         */
    
        public void  addObServer(ObServer obServer);
    
        /**
         * 移除ObServer
         * @param obServer
         */
        public void removeObServer(ObServer obServer);
    
        /**
         * 通知所有的ObServer
         * @param message
         */
        public void notifyObServerAll(String message);
    
        /**
         * 设置更新内容
         * @param message
         */
        public  void setNtifyMessage(String message);
    }
    /**
     * 抽象观察者
     *
     */
    public interface ObServer {
    
        //更新内容
        public void update(String message);
    }
    
    /**
     * 具体观察者
     */
    public class UserObServer implements ObServer {
    
        private String name;
        public UserObServer(String name){
            this.name = name;
        }
        @Override
        public void update(String message) {
                this.name = name;
                this.read(message);
        }
    
        /**
         * 读取消息
         * @param message
         */
        public void read(String message) {
            System.out.println(name + ",老师收到推送消息:" + message);
        }
    }
    /**
     * 抽象主题
     */
    public class WeChatSubject implements AbstractSubject {
        private List<ObServer> obServerList = new ArrayList<ObServer>();
        private String message;
        @Override
        public void addObServer(ObServer obServer) {
            obServerList.add(obServer);
        }
    
        @Override
        public void removeObServer(ObServer obServer) {
            obServerList.remove(obServer);
        }
    
        @Override
        public void notifyObServerAll(String message) {
            for (ObServer server : obServerList) {
                server.update(message);
            }
        }
    
        @Override
        public void setNtifyMessage(String message) {
            this.message = message;
            System.out.println("微信公众号设置message:" + message);
            //通知所有的订阅者接收消息
            notifyObServerAll(message);
        }
    }
    /**
     * 测试类
     */
    public class Test001 {
        public static void main(String[] args) {
            //注册主题
            AbstractSubject weChatSubject = new WeChatSubject();
            weChatSubject.addObServer(new UserObServer("小强"));
            weChatSubject.addObServer(new UserObServer("小张"));
            //发送消息
            weChatSubject.setNtifyMessage("今天下午到我办公室来一趟!!!有重大的事情安排");
        }
    }

    第五、JDK自带观察实现消息发送

    1). Observable类追踪所有的观察者,并通知他们。

    2). Observer这个接口看起来很熟悉,它和我们之前写的类几乎一样。

    /**
     * JDK提供的一种观察者的实现方式,被观察者
     * 自定义一个主题
     */
    public class MessageObServable extends Observable {
    
        private String name;
    
        MessageObServable(String name){
            this.name = name;
        }
    
        public  void publishMessage(Message message){
            System.out.println(message.getName() + "在" + this.name + "上提交了一个问题。");
            //改变数据
            setChanged();
            //通知所有的观察者
            notifyObservers(message);
        }
    
    }
    /**
     * 信息实体
     */
    public class Message {
    
        private String name;
        private String content;
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public String getContent() {
            return content;
        }
    }
    /**
     *自定义观察者
     */
    public class Teacher  implements Observer {
    
        private String name;
        public Teacher(String name){
            this.name = name;
        }
        @Override
        public void update(Observable o, Object arg) {
             MessageObServable userObServer = (MessageObServable) o;
             Message message = (Message) arg;
            System.out.println(this.name+"向"+message.getName()+"描述了:"+message.getContent());
        }
    }
    /**
     * 测试类
     */
    public class Test001 {
        public static void main(String[] args) {
          MessageObServable messageObServable = new MessageObServable("张三");
          messageObServable.addObserver(new Teacher("李四"));
          messageObServable.addObserver(new Teacher("王五"));
          Message message = new Message();
          message.setName("王五");
          message.setContent("今天迟到了!!!!");
          messageObServable.publishMessage(message);
        }
    }
  • 相关阅读:
    【SHOI2002】百事世界杯之旅
    【LGOJ 3384】树链剖分
    [20191006机房测试] 括号序列
    [20191006机房测试] 矿石
    【SHOI2012】回家的路
    [20191005机房测试] Seat
    [20191005机房测试] Silhouette
    每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样
    fgets函数读取最后一行的时候为什么会重复
    c语言中返回的变量地址,其物理地址在?(刨根问底)
  • 原文地址:https://www.cnblogs.com/cxyyh/p/11450823.html
Copyright © 2011-2022 走看看