常用设计模式(10)观察者模式
好久没写推文了,这次重新提起笔,自然还是要从讲故事开始。
在面向对象的程序中,对象和数据库一样,也存在一对多的关系。在数据库中,通过外键关联,可以实现一对多场景下,一行数据修改时,对关联的多行数据进行修改。而在面向对象的程序中,想要做到一个对象修改时,通知其他对象进行修改,则需要用到观察者模式。
观察者模式,及多个对象对A对象进行观察,当A对象状态改变时,这些对象的状态会进行相应的改变。
小洪的故事
出场人物:小洪、大盛
“猴子,你在干嘛呢!”小洪远远看见熟悉的人影在楼顶站着,远远地挥手打招呼到。
“我在观察这个世界呢。”这位被叫猴子的男生回答道。此人名为大盛,因谐音大圣,故被人戏称猴子。
“你最近又在搞啥哲学理念呢。”小洪已经走到他身边,调侃道。
“你听说过双缝干涉实验吗?”
“就是那个证明了波粒二象性的实验?”
“是的,不过实验本身并不可怕,可怕的是发现了观察者这个未解之谜。”大盛的声音越发深沉。
“观察者,那是啥?”
“观察者,即人、摄影机、动物也好,能够给予视线,能观察的物体。我这么跟你说好了,现在有一场NBA总决赛,他的结果会因为你是否看了这场比赛而决定了哪方胜利。“
“那不可能!”小洪一愣。
“是的,那正是观察者——也是量子力学的可怕之处,我们只能观察到现象,而发现不了原因。”
“那你是在…”
“用观察者模式跟你讲一遍你也许就理解了。”大盛顿了顿,“用我们世界的观察者举例子。”
红绿灯
马路上车水马龙,红绿灯是我们能直接感受到的观察者模式。红绿灯这个对象有两种状态:红色和绿色(黄色暂且不计)。当红绿灯转变为绿色,则通知所有车对象行驶,当红绿灯转变为红色,则通知所有车对象停止。
“我们先设计一个红绿灯对象。”大盛说道。
import java.util.ArrayList;
import java.util.List;
public class Light {
private List<Car> observers
= new ArrayList<Car>(); // 观察者列表
private int state; // 状态,1代表红色,2代表绿色
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
System.out.println("红绿灯状态现在改变为" + state);
notifyAllObservers(); // 当状态改变时,通知所有观察者对象
}
public void attach(Observer observer){
observers.add(observer);
}
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update(this.state);
}
}
}
“马路上不止有一种车吧,应该有很多种车,创建个父类吧,这应该是个抽象类,因为没有「车」。”小洪的java知识现在已经非常扎实了。
public abstract class Car {
protected Light light;
public abstract void update(int state);
}
// 实现两种类型的车吧,分别是小轿车和大货车
public class SmallCar extends Car{
// 向被观察者对象注册自己
public BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update(int state) {
if (state == 1) {
System.out.println("小轿车停止行驶");
} else {
System.out.println("小轿车开始行驶");
}
}
}
public class BigCar extends Car{
// 向被观察者对象注册自己
public BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update(int state) {
if (state == 1) {
System.out.println("大货车停止行驶");
} else {
System.out.println("大货车开始行驶");
}
}
}
“好,我们来看看实现吧。”
public class ObserverPatternDemo {
public static void main(String[] args) {
Light light = new Light();
new SmallCar(light);
new BigCar(light);
ligth.setState(1);
ligth.setState(2);
}
}
最终的运行结果
红绿灯状态现在改变为1
小轿车停止行驶
大货车停止行驶
红绿灯状态现在改变为2
小轿车开始行驶
大货车开始行驶
尾声
“如你所见,这是我们正常的观察者,被观察者主动影响观察者。而在量子力学的世界里,观察者是反过来的,观察者会影响被观察者,也就是,因果倒置了”。
“不愧是猴子大王,你懂得真多,这么复杂的物理原理这么容易用代码讲明白了。”小洪日常阿谀奉承了。
“如果量子力学可以像编程这般显而易见就好了。”
他抬头仰望天空,晚霞将天空染成红色,看起来富有生命力。
“我对这个世界一无所知。”他说道。
(本系列暂完)
·