阿尔法的身体内部有一个智能芯片,这个芯片能够根据环境和需求自动改变它的行为模式。当阿尔法需要完成不同任务时,它的内部状态会发生变化,进而改变它的行为,就像是它变成了另一个机器人一样。
一天,智能城的市长接到一个紧急消息:城市的能源核心出了问题,导致整个城市即将陷入黑暗。市长知道只有阿尔法才能解决这个问题,于是他立刻派人去找阿尔法。
阿尔法接到任务后,立即进入"修理模式"。在修理模式下,阿尔法的内部状态变为"工程师状态",它的手臂变成了各种工具,眼睛变成了高精度的扫描仪。阿尔法迅速来到了能源核心,开始检测问题所在。
经过一番检查,阿尔法发现问题出在能源核心的控制系统上。它决定进入"编程模式"。在编程模式下,阿尔法的内部状态变为"程序员状态",它的手指变成了键盘和电缆接口,能够直接连接到控制系统并进行编程。
阿尔法快速编写了一段修复程序,上传到控制系统中。随着程序的运行,能源核心渐渐恢复了正常,整个智能城重新亮起了光芒。
然而,阿尔法的任务并没有结束。智能城的一所学校发生了火灾,学生们被困在教学楼里。阿尔法接到新的任务后,立即进入"救援模式"。在救援模式下,阿尔法的内部状态变为"救援状态",它的身体变得更加坚固,装备了各种救援工具和灭火设备。
阿尔法迅速赶到现场,使用灭火器扑灭了火焰,随后用强有力的臂膀破开被困学生们的教室门,将他们一个个安全地带了出来。
观察者模式(Observer Pattern)
状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将状态相关的行为封装在状态对象中,使得当对象的内部状态改变时,其行为也会随之改变,类似于它改变了其类。
核心组件
- Subject(主题):主题保存了一组观察者,提供用于增加或删除观察者的接口。
- Observer(观察者):为那些在主题状态改变时需要获得通知的对象定义一个更新接口。
- ConcreteSubject(具体主题):存储具体观察者关心的数据,发送通知给观察者,通常包含对具体数据的增删改操作。
- ConcreteObserver(具体观察者):实现观察者接口,以便在得到通知时更新自身。
适用场景
- 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时 :
- 观察者模式允许你独立地扩展或复用核心功能。
- 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象需要改变时 :
- 观察者模式可以让你在不修改这些类的前提下增加新的观察者。
- 当一个对象必须通知其他对象,但你希望避免做成这些对象之间的紧密耦合时 :
- 观察者模式提供了一种松耦合的设计解决方案。
实现实例
以新闻应用为例,其中新闻发布系统(主题)需要通知所有订阅者(观察者)新闻更新。
主题接口(Subject Interface)
定义了附加和删除观察者的方法,以及通知观察者的方法。
java
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
具体主题(Concrete Subject)
存储状态,并在状态改变时通知观察者。
java
public class NewsAgency implements Subject {
private List<Observer> observers = new ArrayList<>();
private String news;
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(news);
}
}
public void setNews(String news) {
this.news = news;
notifyObservers();
}
}
观察者接口(Observer Interface)
定义更新接口,用于获取状态改变通知。
java
public interface Observer {
void update(String news);
}
具体观察者(Concrete Observer)
实现观察者接口,根据通知更新自己。
java
public class NewsChannel implements Observer {
private String news;
@Override
public void update(String news) {
this.news = news;
System.out.println("News Updated: " + news);
}
}
客户端代码(Client Code)
演示如何使用观察者模式。
java
public class Client {
public static void main(String[] args) {
NewsAgency newsAgency = new NewsAgency();
NewsChannel channel = new NewsChannel();
newsAgency.registerObserver(channel);
newsAgency.setNews("New update on AI technology!");
}
}
优缺点
优点
- 支持广播通信 :
- 观察者模式提供了一种订阅机制,可以实现消息的广播。
- 应用松耦合 :
- 主题与观察者之间使用抽象耦合,可以轻松地添加新的观察者。
缺点
- 可能引发无序的更新 :
- 如果观察者的更新方法引发循环依赖,可能导致系统行为难以预测。
- 当观察者和主题之间的依赖关系复杂时,可能需要额外的维护成本。
类图
+----------------+ +------------------+
| Subject |-------->| Observer |
+----------------+ +------------------+
| + registerObserver() | + update() |
| + removeObserver() | |
| + notifyObservers() +------------------+
+----------------+ |
| | |
+----------------+ |
|
+-------------------+--------+----------------+
| | | |
+---------------+ +-----------------+ +----------------+ +--------------+
|ConcreteSubject| |ConcreteObserver1| |ConcreteObserver2| | ... |
+---------------+ +-----------------+ +----------------+ +--------------+
| + setNews() | | + update() | | + update() | | + update() |
+---------------+ +-----------------+ +----------------+ +--------------+
总结
观察者模式提供了一种优雅的方式来实现对象间的通信,特别适用于状态变化需要通知多个对象的场景。通过将主题与观察者解耦,增加了系统的灵活性和可扩展性,同时也需注意避免循环依赖和更新顺序问题。