设计模式之观察者模式(Observer pattern)
2024-08-30 19:07:01
最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下:
上课铃声响起,学生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();
} }
输出结果如下:
最新文章
- 我的window10
- cosbench read异常解决办法。 Unable to verify integrity of data download. Client calculated content hash didn't match hash calculated by Amazon S3. The data may be corrupt.
- javac找不到或无法加载主类 com.sun.tools.javac.Main
- Android Studio 使用技巧
- Python自动补全
- bootstrap 响应式布局
- 20145215《Java程序设计》第4周学习总结
- [Effective JavaScript 笔记]第31条:使用Object.getPrototypeOf函数而不要使用__proto__属性
- Android 使用FACE++架构包实现人脸识别
- Q查询
- sqlite-dbeaver-heidisql
- CoreAnimation的使用
- Mongodb的集合插入一个字段
- python3列表(元组)练习
- tomcat通过一个端口号实现多域名访问
- Spring Boot 启动:No active profile set, falling back to default profiles: default
- c++符号常量:limits头文件
- APICloud之封装webApp
- flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象)
- Python文本爬虫实战
热门文章
- [Vijos] 河蟹王国
- Codeforces Round #298 (Div. 2) D. Handshakes [贪心]
- angularjs ngRoute的使用简单例子
- 【转载】js中对象的使用
- Python基础之 一 文件操作
- 将oracle10g 升级至10.2.0.4
- socket的bind函数是不是只能绑定本地IP,不能绑定外网IP么?
- 浏览器websocket
- [NPM] Create a new project using the npm init <;initializer>; command
- 白话空间统计之四:P值和Z值(上):零如果