观察者模式

  • 概述
  • UML类图
  • 代码栗子
  • 总结

概念

  • 概念 观察者模式又叫做发布-订阅模式,观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新(来源百度百科)。栗如,抗日战争中我方地下党人会密切监视日军的一举一动,根据它们的战略部署及时做出相应的返回,这也就是观察者模式(我军->观察者;日军->被观察者)
  • 作用
    1. 观察者和被观察者之间是抽象耦合
    2. 建立一套触发机制(触发链);栗如(我方地下党观察到日军要进行扫荡,返回基地向班长汇报,班长一级向上汇报最终首长发出应对的方针)

UML 类图

代码栗子

  • 观察者

    注意这里的接口 Observer ,这是观察要实现的接口,JDK 原生提供了 观察者接口的定义,这里就直接使用JDK自带的

    public class ClassLeader implements Observer {
        /**
         * 班干部观察学生的上课纪律情况
         *
         * @param observable
         * @param obj
         */
        @Override
        public void update(Observable observable, Object obj) {
            System.out.println("班干部:观察到"+obj.toString()+",开始向老师汇报了...");
            this.reportToTeacher(obj.toString());
            System.out.println("班干部:报告完毕...");
        }
        
        /**
         * 报告给老师
         *
         * @param reportContext
         */
        private void reportToTeacher(String reportContext) {
            System.out.println("班干部:报告老师!" + reportContext);
        }
    }
    
  • 被观察者

    Observable 接口也是使用JDK的原生定义的

    public interface IStudent {
        
        /**
         * 学生名字
         * @return
         */
        String getName() ;
        /**
         * 吃零食
         */
        void eatFood();
        
        /**
         * 上课聊天
         */
        void chat();
    }
    
    public class ZhangSan extends Observable implements IStudent {
        /**
         * 学生名称
         *
         * @return
         */
        @Override
        public String getName() {
            return "张三";
        }
        
        @Override
        public void eatFood() {
            System.out.println(this.getName()+":上课吃零食...");
            /**
             * 通知所有的观察者
             */
            super.setChanged();
            super.notifyObservers(this.getName()+"上课吃零食");
        }
        
        
        @Override
        public void chat() {
            System.out.println(this.getName()+":上课聊天、玩QQ...");
            super.setChanged();
            this.notifyObservers(this.getName()+"上课聊天、玩QQ");
        }
    }
    
  • test

    public class Main {
        public static void main(String[] args) {
            //班干部
            Observer classLadeLr = new ClassLeader();
            ZhangSan zhangSan = new ZhangSan();
            zhangSan.addObserver(classLadeLr);
            zhangSan.chat();
            zhangSan.eatFood();
        }
    }
    
  • 运行效果

image.png

总结

  • 观察者模式的应用极其广泛,但是要注意它的观察链(触发链),栗子 A观察B ,触发C; C观察D ,触发E;E观察F ,触发A; 这样一条触发链后期维护的成本很大

参考资料

书籍《设计模式之禅》

posted @ 2019-04-06 18:23  tanoak  阅读(120)  评论(0编辑  收藏  举报