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

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

输出结果如下:

最新文章

  1. 我的window10
  2. 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.
  3. javac找不到或无法加载主类 com.sun.tools.javac.Main
  4. Android Studio 使用技巧
  5. Python自动补全
  6. bootstrap 响应式布局
  7. 20145215《Java程序设计》第4周学习总结
  8. [Effective JavaScript 笔记]第31条:使用Object.getPrototypeOf函数而不要使用__proto__属性
  9. Android 使用FACE++架构包实现人脸识别
  10. Q查询
  11. sqlite-dbeaver-heidisql
  12. CoreAnimation的使用
  13. Mongodb的集合插入一个字段
  14. python3列表(元组)练习
  15. tomcat通过一个端口号实现多域名访问
  16. Spring Boot 启动:No active profile set, falling back to default profiles: default
  17. c++符号常量:limits头文件
  18. APICloud之封装webApp
  19. flask模板的基本用法(定界符、模板语法、渲染模板),模板辅助工具(上下文、全局对象、过滤器、测试器、模板环境对象)
  20. Python文本爬虫实战

热门文章

  1. [Vijos] 河蟹王国
  2. Codeforces Round #298 (Div. 2) D. Handshakes [贪心]
  3. angularjs ngRoute的使用简单例子
  4. 【转载】js中对象的使用
  5. Python基础之 一 文件操作
  6. 将oracle10g 升级至10.2.0.4
  7. socket的bind函数是不是只能绑定本地IP,不能绑定外网IP么?
  8. 浏览器websocket
  9. [NPM] Create a new project using the npm init <initializer> command
  10. 白话空间统计之四:P值和Z值(上):零如果