设计模式之观察者模式(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();
    }

}

输出结果如下:

原文地址:https://www.cnblogs.com/hiver/p/7441028.html