• 设计模式之观察者模式(Observer pattern)


    最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下:

    上课铃声响起,学生A/B/C/D进入教室;下课铃声响起,学生A/B/C/D离开教室。

    要求使用设计模式的思想完成铃与学生两个类的解耦并画出UML类图。

    看到这道题之后自己第一时间便想到了装饰器模式,定义一个装饰类继承铃的接口,在上课铃与下课铃的接口中添加学生们的动作,UML类图如下:

    最后的确做到了解耦,但总觉得与装饰器模式的应用场景不太匹配,最后面试官给了个提示——观察者模式——于是豁然开朗,本题的场景毫无疑问更适合使用观察者模式来解决,观察者模式定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新

    该道题使用观察者模式的UML类图如下:

    实现代码如下(Java:jdk1.8.0_144):

    import java.util.Observable;
    
    public abstract class IBell extends Observable {
        public enum State {
            上课, 下课
        }
    
        public abstract void firstRing();
    
        public abstract void secondRing();
    }
    public class Bell extends IBell {
    
        @Override
        public void firstRing() {
            System.out.println("上课铃响了!!!");
            super.setChanged();// 修改对象状态才能触发观察者的通知事件
            this.notifyObservers(State.上课);
        }
    
        @Override
        public void secondRing() {
            System.out.println("下课铃响了!!!");
            super.setChanged();// 修改对象状态才能触发观察者的通知事件
            this.notifyObservers(State.下课);
        }
    
    }
    import java.util.Observable;
    import java.util.Observer;
    
    import org.lxp.dailylog.web.util.IBell.State;
    
    public abstract class IStudent implements Observer {
        public abstract void enterClassRoom();
    
        public abstract void leaveClassRoom();
    
        @Override
        public void update(Observable o, Object arg) {
            switch (State.valueOf(arg.toString())) {
            case 上课:
                enterClassRoom();
                break;
            case 下课:
                leaveClassRoom();
                break;
            }
        }
    
    }
    public class Student extends IStudent {
        private String name;
    
        public Student(String name) {
            this.name = name;
        }
    
        @Override
        public void enterClassRoom() {
            System.out.println("Student " + this.name + " enters classroom");
        }
    
        @Override
        public void leaveClassRoom() {
            System.out.println("Student " + this.name + " leaves classroom");
        }
    }
    public class Test {
    
        public static void main(String[] args) {
            Student A = new Student("A");
            Student B = new Student("B");
            Student C = new Student("C");
            Student D = new Student("D");
            Bell bell = new Bell();
            bell.addObserver(D);
            bell.addObserver(C);
            bell.addObserver(B);
            bell.addObserver(A);
            bell.firstRing();
            bell.secondRing();
        }
    
    }

    输出结果如下:

  • 相关阅读:
    Python 开发中easy_install的安装及使用
    Python 对象的深拷贝与浅拷贝 -- (转)
    Python 语言使用中遇到的问题汇总
    Python 源码学习之内存管理 -- (转)
    Python 对象模型 -- (转)
    Python3.3.3 安装(Linux系统)
    angular-file-upload API angular文件上传插件
    html5上传文件并监听进度
    angular 服务
    skrollr 中文教程
  • 原文地址:https://www.cnblogs.com/hiver/p/7441028.html
Copyright © 2020-2023  润新知