观察者模式
-
什么是观察者模式
定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己.别名依赖(Dependents), 发布-订阅( publish - subscribe) -
什么场景会用到命令模式
一个对象的改变需要同时改变其它对象的时候,而且不知道具体有多少个对象有待改变时。想想以前的报纸订阅,如果我们定了人名日报,每到早上都会有送报的上门,不管你爱看不爱看这阵子的新闻,只要报纸一出版就会很快送达,如果订阅者最近没有时间看新闻来, 只要取消订阅,接下来新出版的报纸就不会再送了。
我们拟定一个场景,办公室的所有人都无所事事,程序员,PO和TEAMLEADER,但是当然大家都怕老板过来查岗,所以就需要一个类似哨兵的帮忙来监视老板的行径,这时候前台就起到很大的作用了,当老板回来的时候肯定先经过前台,这时候前台再去通知所有人,告诉大家该做正经事了。
public interface Employee {
void update();
}
public interface Action {
void action();
}
public class Developer implements Employee, Action {
@Override
public void action() {
System.out.println("coding");
}
@Override
public void update() {
action();
}
}
public class ProductManager implements Employee, Action {
@Override
public void action() {
System.out.println("discuss requirements");
}
@Override
public void update() {
action();
}
}
public class TeamLeader implements Employee, Action {
@Override
public void action() {
System.out.println("writing document");
}
@Override
public void update() {
action();
}
}
前台
public class Receptionist implements Employee{
List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void cancelEmployee(Employee employee) {
Objects.requireNonNull(employees);
employees.remove(employee);
}
@Override
public void update() {
System.out.println("boss is coming");
notifyEmployees();
}
private void notifyEmployees() {
employees.forEach(Employee::update);
}
}
测试如下
public static void main(String[] args) {
Receptionist receptionist = new Receptionist();
receptionist.addEmployee(new Developer());
receptionist.addEmployee(new ProductManager());
Employee teamLeader = new TeamLeader();
receptionist.addEmployee(teamLeader);
receptionist.cancelEmployee(teamLeader);
receptionist.update();
}
-
适用性
-在以下任一情况下可以使用观察者模式 :
• 当一个抽象模型有两个方面 , 其中一个方面依赖于另一方面。将这二者封装在独立的对
象中以使它们可以各自独立地改变和复用。
• 当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
• 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些
对象是紧密耦合的。JDK里面内置了观察者模式的功能,在java.util包内的Observer接口和Observable类,基本上实现类似,就不一一讲解了。有兴趣的大家可以去查看它的源码。
相关参考:
<大话设计模式>,<设计模式,可复用面向对象软件的基础>,<Head First 设计模式>
源码在此