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

本文介绍了一个使用观察者模式实现的课堂铃声系统案例。通过Java代码演示如何将铃声与学生的动作解耦,并展示了具体的实现过程及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

上课铃声响起,学生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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值