zoukankan      html  css  js  c++  java
  • 设计模式-6-观察者

    简介:被观察者管理着观察者,当被观察者发生变化,主动向观察者发出通知

    目的:建立对象之间的依赖关系, 对象发生改变自动通知其他对象,其他对象作出相应的反应

    总结:订阅-发布模式

    组成: 观察者, 被观察者

    实现方式: 1-自定义    2-JDK

    一, 自定义方式

    1,观察者

    package com.design.f.observer.base;
    /**
     * 观察者接口
     */
    public interface ObserverService {
        
        /**
         * 被观察者发生改变需要观察者执行的动作
         */
        Boolean update();
    
    }
    package com.design.f.observer.base;
    
    /**
     * 观察者A
     */
    public class ObserverAServiceImpl implements ObserverService {
    
        @Override
        public Boolean update() {
            System.out.println("收到被观察者的变化    --> 观察者A  -->  相应的处理 ");
            return true;
        }
    
    }
    package com.design.f.observer.base;
    
    /**
     * 观察者B
     */
    public class ObserverBServiceImpl implements ObserverService {
    
        @Override
        public Boolean update() {
            System.out.println("收到被观察者的变化    --> 观察者B  -->  相应的处理 ");
            return true;
        }
    
    }

    2,被观察者

    package com.design.f.observer.base;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 被观察者
     */
    public class Observable {
        
        
        //1-记录观察者
        private List<ObserverService> observers = new ArrayList<ObserverService>();
        public Boolean addObserver(ObserverService observerService){
            return observers.add(observerService);
        }
        
        
        //2-发生改变的动作
        public void changed(){
            System.out.println("被观察者已发生变化   ... ... ");
            notifyObserver();
            
        }
        
        //3-通知观察者
        private void notifyObserver(){
            System.out.println("被观察者开始通知观察者   ... ... ");
            for(ObserverService observerService : observers){
                observerService.update();
            }
        }
    
    }

    3,Main

    package com.design.f.observer.base;
    
    /**
     * 6-观察者模式
     * 简介:一个对象状态的改变需要通知很多对这个对象关注的一系列对象,就可以使用观察者模式。
     * 用例:文件上传的进度显示,被关注的博主发布新文章通知关注着,小说网站的订阅者在发布新的小说后通知订阅者
     * 
     * 事件驱动模型
     * 观察者更多的强调的是发布-订阅式的问题处理,而事件驱动则更多的注重于界面与数据模型之间的问题
     * 被观察者 = 事件源
     * 观察者     = 监听器
     * 
     * 用例:Tomcat的启动用到的listener监听器,Spring启动添加监听器随着Tomcat的启动IOC容器也开始启动
     */
    public class MainTest {
        
        public static void main(String[] args) {
            /**
             * 观察者模式-自定义
             */
            //1-创建观察者
            ObserverService observerA = new ObserverAServiceImpl();
            ObserverService observerB = new ObserverBServiceImpl();
            //2-向被观察者添加观察者
            Observable observed = new Observable();
            observed.addObserver(observerA);
            observed.addObserver(observerB);
            //3-触发被观察者发生改变,通知观察者
            observed.changed();
        }
    }

    4,Result

    被观察者已发生变化   ... ... 
    被观察者开始通知观察者   ... ... 
    收到被观察者的变化    --> 观察者A  -->  相应的处理 
    收到被观察者的变化    --> 观察者B  -->  相应的处理 

     二,JDK实现方式

    1,基础用户类

    package com.design.f.observer.base;
    
    import java.io.Serializable;
    /**
     * 用户
     */
    public class User implements Serializable{
        
        private static final long serialVersionUID = 158957714520271405L;
        private String userName;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        @Override
        public String toString() {
            return super.toString();
        }
        
    }

    2,观察者

    package com.design.f.observer.base;
    
    import java.util.Observable;
    import java.util.Observer;
    
    /**
     * 观察者
     */
    public class Reader implements Observer {
        
        //读者用户信息
        private User user;
        
        public Reader(String userName){
            user = new User();
            user.setUserName(userName);
        }
        
        //关注作者
        public void subscriptionWriter(String writerName){
            
            //检查作者是否存在
            if(WriterManager.getInstance().isWriter(writerName)){
                WriterManager.getInstance().getWriter(writerName).addObserver(this);
            }
            
        }
        
        //取消关注
        public void unSubscriptionWriter(String writerName){
            
            //检查作者是否存在
            if(WriterManager.getInstance().isWriter(writerName)){
                WriterManager.getInstance().getWriter(writerName).deleteObserver(this);
            }
        }
        
        //收到被观察者的要执行的动作
        @Override
        public void update(Observable o, Object arg) {
            
            if(o instanceof Writer){
                Writer writer = (Writer) o;
                System.out.println("读者 : " + user.getUserName() + "  收到作者: " + writer.getUser().getUserName() + "  发布的新书: " +writer.getLastBook());
            }
        }
        
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
    
    }

    3,被观察者

    package com.design.f.observer.base;
    
    import java.util.Observable;
    /**
     * 被观察者
     */
    public class Writer extends Observable {
    
        //作者用户信息
        private User user;
        //作者新书
        private String lastBook;
        
        public Writer(String userName){
            
            //初始化用户信息
            user = new User();
            user.setUserName(userName);
            
            //将作者添加到作者管理器中
            WriterManager.getInstance().addWriter(this);
        }
        
        //作者发布新书动作
        public void pushBook(String bookName){
            System.out.println("作者 : " + user.getUserName() + ";   发布了新书: " + bookName + " ... ... ");
            lastBook = bookName;
            
            //设置被观察发生改变的状态,并通知观察者
            setChanged();
            notifyObservers();
        }
        
        
        public String getLastBook() {
            return lastBook;
        }
        public void setLastBook(String lastBook) {
            this.lastBook = lastBook;
        }
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        
    }

    4,观察者管理器

    package com.design.f.observer.base;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 观察者管理器 
     */
    public class WriterManager {
        
        //1-作者集合
        private Map<String, Writer> writerMap = new HashMap<String, Writer>();
        
        //2-添加作者
        public void addWriter(Writer writer){
            writerMap.put(writer.getUser().getUserName(), writer);
        }
        
        //3-删除作者
        public void removeWriter(Writer writer){
            writerMap.remove(writer.getUser().getUserName());
        }
        
        //4-获取作者
        public Writer getWriter(String writerName){
            return writerMap.get(writerName);
        }
        
        //5-作者是否存在
        public Boolean isWriter(String writerName){
            return writerMap.containsKey(writerName);
        }
        
        //获取作者集合单例
        private WriterManager(){}
        public static WriterManager getInstance(){
            return WriterManagerInstance.writerManager;
        }
        private static class WriterManagerInstance{
            static WriterManager writerManager = new WriterManager();
        }
        
    
        public Map<String, Writer> getWriterMap() {
            return writerMap;
        }
        public void setWriterMap(Map<String, Writer> writerMap) {
            this.writerMap = writerMap;
        }
    
    }

    5,Main

    package com.design.f.observer.base;
    
    /**
     * 6-观察者模式
     * 简介:一个对象状态的改变需要通知很多对这个对象关注的一系列对象,就可以使用观察者模式。
     * 用例:文件上传的进度显示,被关注的博主发布新文章通知关注着,小说网站的订阅者在发布新的小说后通知订阅者
     * 
     * 事件驱动模型
     * 观察者更多的强调的是发布-订阅式的问题处理,而事件驱动则更多的注重于界面与数据模型之间的问题
     * 被观察者 = 事件源
     * 观察者     = 监听器
     * 
     * 用例:Tomcat的启动用到的listener监听器,Spring启动添加监听器随着Tomcat的启动IOC容器也开始启动
     */
    public class MainTest {
        
        public static void main(String[] args) {
            
            /**
             * 观察者模式-自定义
             */
    //        //1-创建观察者
    //        ObserverService observerA = new ObserverAServiceImpl();
    //        ObserverService observerB = new ObserverBServiceImpl();
    //        //2-向被观察者添加观察者
    //        Observable observed = new Observable();
    //        observed.addObserver(observerA);
    //        observed.addObserver(observerB);
    //        //3-触发被观察者发生改变,通知观察者
    //        observed.changed();
            
            /**
             * 观察者模式-JDK
             */
            
            //1-创建读者
            Reader readerA = new Reader("读者A");
            Reader readerB = new Reader("读者B");
            Reader readerC = new Reader("读者C");
            Reader readerD = new Reader("读者D");
            
            //2-创建作者
            Writer writerA = new Writer("莫言");
            Writer writerB = new Writer("路遥");
            
            //3-将读者关注到作者
            readerA.subscriptionWriter("莫言");
            readerB.subscriptionWriter("莫言");
            readerC.subscriptionWriter("莫言");
            readerD.subscriptionWriter("莫言");
            readerA.subscriptionWriter("路遥");
            readerB.subscriptionWriter("路遥");
            
            //5-作者发布新书
            writerA.pushBook("平凡的世界");
            writerB.pushBook("悲惨的世界");
            
            //6-读者A取消路遥关注
            readerA.unSubscriptionWriter("路遥");
            writerB.pushBook("十月围城");
        }
    
    }

    6,Result

    作者 : 莫言;   发布了新书: 平凡的世界 ... ... 
    读者 : 读者D  收到作者: 莫言  发布的新书: 平凡的世界
    读者 : 读者C  收到作者: 莫言  发布的新书: 平凡的世界
    读者 : 读者B  收到作者: 莫言  发布的新书: 平凡的世界
    读者 : 读者A  收到作者: 莫言  发布的新书: 平凡的世界
    作者 : 路遥; 发布了新书: 悲惨的世界 ... ... 读者 : 读者B 收到作者: 路遥 发布的新书: 悲惨的世界 读者 : 读者A 收到作者: 路遥 发布的新书: 悲惨的世界
    作者 : 路遥; 发布了新书: 十月围城 ... ... 读者 : 读者B 收到作者: 路遥 发布的新书: 十月围城
  • 相关阅读:
    python算法(1)抓交通肇事犯
    vue(24)网络请求模块axios使用
    vue(23)Vuex的5个核心概念
    vue(22)Vuex的安装与使用
    JMeter分布式压测配置(五)
    命令行执行Jmeter脚本(四)
    BeanShell(二)
    Jmeter之测试片段(八)
    服务器资源监控之Perfmon
    Jmeter之线程组(四)
  • 原文地址:https://www.cnblogs.com/wanhua-wu/p/7201646.html
Copyright © 2011-2022 走看看