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

    什么是观察者模式

      观察者模式:定义对象之间的一对多依赖,当一个对象的改变状态时,它的依赖者都会收到通知并自动更新。这里就用报社、人来分析,如果有人想看报纸就可以向报社订阅,如果已经订阅的人不想看报纸可以向报社注销,而对于报社而言,它只会把报纸发给订阅的人群,这里的报社就是观察者模式中的主题(Subject),人就是观察者(Observer),观察者向主题注册自己就可以在主题改变时收到通知。

    UML图

    代码实现

    /**
     * 观察者模式的主题,用于注册、移除、通知观察者
     */
    public interface Subject {
        /**
         * 新增观察者
         */
        void registerObserver(Observer observer);
    
        /**
         * 移除观察者
         */
        void removeObserver(Observer observer);
    
        /**
         * 通知观察者
         */
        void notifyObserver(String newspaperName);
    }
    
    /**
     * 观察者接口类
     */
    public interface Observer {
    
        /**
         * 被通知时做的操作
         */
        void update(String newspaperName);
    
    }
    

      上面时观察者模式的两个核心类,下面时具体的应用,首先是主题实现类-NewspaperOffice,observerList 保存所有的观察者,

    import java.util.ArrayList;
    import java.util.List;
    
    public class NewspaperOffice  implements Subject{
    
        private List<Observer> observerList = new ArrayList<>();
    
        @Override
        public void registerObserver(Observer observer) {
            observerList.add(observer);
        }
    
        @Override
        public void removeObserver(Observer observer) {
            observerList.remove(observer);
        }
    
        /**
         * 通知观察者们
         */
        @Override
        public void notifyObserver(String newspaperName) {
            observerList.forEach((b) -> b.update(newspaperName));
        }
    
    }
    

      这里是具体的观察者,也就是被通知的对象

    /**
     * 观察者A
     */
    public class CustomerA implements Observer{
    
        private Subject subject;
    
        public CustomerA(Subject subject) {
            this.subject = subject;
            subject.registerObserver(this);
        }
    
        @Override
        public void update(String newspaperName) {
            System.out.println("CustomerA:《" + newspaperName + "》发布了");
        }
    
    }
    
    
    /**
     * 观察者B
     */
    public class CustomerB implements Observer {
    
        private Subject subject;
    
        public CustomerB(Subject subject) {
            this.subject = subject;
            subject.registerObserver(this);
        }
    
        @Override
        public void update(String newspaperName) {
            System.out.println("CustomerB:《" + newspaperName + "》发布了");
        }
    
    }
    
    

      测试上面写的简易观察者模式实现

    public class ObserverTest {
        public static void main(String[] args) {
            Subject subject = new NewspaperOffice();
            new CustomerA(subject);
            // 注册观察者B
            new CustomerB(subject);
            // 通知观察者们
            subject.notifyObserver("日报A");
            System.out.println("========================================");
            subject.notifyObserver("日报B");
        }
    }
    

      测试结果

    总结

      从上面的例子分析,主题和观察则都是接口,主题通过接口通知依赖它的所有观察者做某个操作(广播通信),只要知道具体对象的列表,而不需要知道某个具体的对象,上面例子NewspaperOffice只需拥有Observer数组,至于具体的某个Observer并不关注,降低了对象之间的耦合度,这里也是设计原则"针对接口编程,不针对实现编程"的体现。

  • 相关阅读:
    自己开发网站全文检索系统
    中国摇滚二十年(经典100首歌曲)
    有一首歌
    Snoopy.class.php使用手册
    wp-Syntax 插件使用方法
    rabbitmq使用
    小程序相关功能的实现
    知识链接
    celery使用
    阿里云服务器部署项目注意事项
  • 原文地址:https://www.cnblogs.com/winkin/p/11013184.html
Copyright © 2011-2022 走看看