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

    观察者模式,有时又被称为模型-视图(View)模式,有的叫发布-订阅模式,监听模式或从属者模式,是软件设计模式的一种。

    观察者: 观察目标对象的状态、行为等的的主体。观察将自己存放到被观察对象中,被观察对象将观察者存放
    在一个容器(Vector)里。
    被观察的对象:被观察者所研究或关注的对象。当被观察的对象发生了某种变化时,将循环遍历容器中的所
    有观察者,并将发生的变化通知予观察者。

    场景:用户张三、李四、王五(观察者)都关注了微信公众号(被观察者),当微信公众号发布消息后会给观察者推送消息。

    利用观察者模式:微信公众号发布消息,调用原来的实现的观察者接口。

    以下代码实现为,用户(观察者)关注微信公众号(被观察者)后,微信公众号会保存一个用户的集合在类中。然后微信公众号发布消息,就会触发遍历集合中的所有用户,调用每个用户的方法,推送消息。

    //main方法
    public class DemoMain {
        public static void main(String[] args) {
            WeChatOfficialAccount wechat = new WeChatOfficialAccount("微信公众号");
            WeChatUser wechatUser = new WeChatUser("张三");
            wechat.addObserver(wechatUser);
            wechatUser = new WeChatUser("李四");
            wechat.addObserver(wechatUser);
            wechatUser = new WeChatUser("王五");
            wechat.addObserver(wechatUser);
            wechat.postMessage("改变中国IT教育,我们正在行动...");
        }
    }
    
    
    /**
    * 观察者接口
    */
    public interface Observer {
    
        /**
              * 被观察体发生变化时调用的方法,用来通知观察者
              * @param args
              */
        void update(Object args);
    
        /**
          * 获取观察者名称
          * @return
          */
        String getName();
    
    
    }
    
    
    /**
     *  * 被观察者接口
     * 
     */
    public interface Observable {
        /**
         *      * 添加观察者
         *      * @param observer
         *      
         */
        void addObserver(Observer observer);
    
        /**
         *      * 解除观察者
         *      * @param observer
         *      
         */
        void delObserver(Observer observer);
    
        /**
         *      * 通知所有的观察者
         *      
         */
        void notifiyObservers(Object args);
    }
    
    
    
    
    /**
     * 微信用户
     */
    public class WeChatUser implements Observer {
        private String username;
    
        public WeChatUser(String username) {
            this.username = username;
        }
    
        @Override
        public void update(Object args) {
            readMessage((String) args);
        }
    
        public void readMessage(String message) {
            System.out.println(String.format("%s  读取了信息‐>  %s", this.username, message));
        }
    
        @Override
        public String getName() {
            return this.username;
        }
    }
    
    
    
    /**
     * 被观察者,微信公众号
     */
    public class WeChatOfficialAccount implements Observable {
        private String name;
        /**
         * 保存所有的观察者
         */
        private Vector<Observer> observers;
    
        public WeChatOfficialAccount(String name) {
            this.name = name;
            this.observers = new Vector<Observer>();
        }
    
        @Override
        public synchronized void addObserver(Observer observer) {
            System.out.println(observer.getName() + " 关注了公众号 " + this.name);
            this.observers.add(observer);
        }
    
        @Override
        public synchronized void delObserver(Observer observer) {
            observers.remove(observer);
        }
    
        @Override
        public void notifiyObservers(Object args) {
            Observer[] arr = observers.toArray(new Observer[]{});
            for (int i = arr.length - 1; i >= 0; i--) {
                // 通知每个观察者
                arr[i].update(args);
            }
        }
    
        /**
         * 发布新的消息
         *
         * @param message
         */
        public void postMessage(String message) {
            System.out.println(name + "微信公众号发布新的消息: " + message);
            notifiyObservers(message);
        }
    }

    输出结果:

    张三 关注了公众号 微信公众号
    李四 关注了公众号 微信公众号
    王五 关注了公众号 微信公众号
    微信公众号微信公众号发布新的消息: 改变中国IT教育,我们正在行动...
    王五 读取了信息‐> 改变中国IT教育,我们正在行动...
    李四 读取了信息‐> 改变中国IT教育,我们正在行动...
    张三 读取了信息‐> 改变中国IT教育,我们正在行动...

  • 相关阅读:
    TODO C++ lambda表达式
    C++ Map实践
    【转】C++ typedef typename 作用
    C++ Vector实践
    再学引用
    设置table中的td一连串内容自动换行
    JavaScript中基本数据类型和引用数据类型的区别
    “浏览器模式”和“文档模式”之间的区别
    浏览器模式与文档模式区别
    HTML5中的data-*属性和jQuery中的.data()方法使用
  • 原文地址:https://www.cnblogs.com/chenfx/p/14725394.html
Copyright © 2011-2022 走看看