目录
观察者模式定义
观察者模式又叫做发布-订阅(Publish/Subscribe)模式。观察者模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

优点
-
松散耦合:主题对象和观察者对象之间的关系是松散耦合的,它们相互独立,易于维护和扩展。
-
可扩展性:可以轻松地添加新的观察者对象,以响应主题状态的变化,而不需要修改主题类。
-
复用性:观察者模式支持多个观察者对象共享同一个主题对象,提高了代码的复用性。
缺点
-
过多的通知:如果主题对象频繁地改变状态,会导致观察者对象频繁地接收通知,可能会引起性能问题。
-
可能引发循环依赖:如果观察者对象之间相互依赖,可能会导致循环依赖问题,需要小心处理。
观察者模式结构说明
-
主题(Subject):维护一个观察者列表,并提供方法用于注册、删除和通知观察者。
-
具体主题(Concrete Subject):实现主题接口,负责维护具体的状态,并在状态发生变化时通知观察者。
-
观察者(Observer):定义了一个更新接口,用于在主题状态变化时接收通知和更新自身状态。
-
具体观察者(Concrete Observer):实现观察者接口,负责在接收到主题通知时执行相应的操作。
工作流程
-
具体主题对象维护一个观察者列表。
-
当具体主题对象的状态发生变化时,它会遍历观察者列表,依次通知每个观察者对象。
-
每个观察者对象接收到通知后,执行自己的更新操作。
代码练习
观察者模式属于行为型设计模式。自来水公司负责定期通知小区业主当月是否需要缴纳水费的场景可以适用。
1.创建抽象主题FeesSubject。
public interface FeesSubject {
void addObserver(FeesObserver observer);
void removeObserver(FeesObserver observer);
void notifyObserver();
}
2.创建抽象观察者FeesObserver,定义一个根据主题状态变化进行更新的方法。
public interface FeesObserver {
void update(int state);
}
3.创建具体主题自来水公司WaterCompany。
public class WaterCompany implements FeesSubject{
private List<FeesObserver> observers = new ArrayList<>();
private int state;
public void setState(int state) {
this.state = state;
notifyObserver();
}
@Override
public void addObserver(FeesObserver observer) {
this.observers.add(observer);
}
@Override
public void removeObserver(FeesObserver observer) {
this.observers.remove(observer);
}
@Override
public void notifyObserver() {
for (FeesObserver o:observers) {
o.update(state);
}
}
}
4.创建具体观察者小区业主ComunityOwner
public class ComunityOwner implements FeesObserver{
private int state;
@Override
public void update(int state) {
this.state = state;
System.out.println("当月是否需要缴纳水费:" + state);
}
}
5.客户端代码
public class Client {
public static void main(String[] args) {
WaterCompany company = new WaterCompany();
FeesObserver observer = new ComunityOwner();
FeesObserver observer1 = new ComunityOwner();
company.addObserver(observer);
company.addObserver(observer1);
company.setState(1);
}
}
应用场景
观察者模式适用于以下情况:
-
当一个对象的状态变化需要通知多个其他对象,并且这些对象不同步更新时,可以考虑使用观察者模式。
-
当一个对象需要在不同情况下通知不同的观察者对象时,观察者模式非常有用。
-
当一个对象的状态变化可能导致其他对象的状态变化,形成一种依赖关系时,观察者模式可以用于管理这种依赖关系。
本质
观察者模式的本质是定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并自动更新。
设计原则
- 开闭原则(Open-Closed Principle):观察者模式遵循开闭原则,因为可以通过添加新的观察者对象来扩展系统,而不需要修改现有的主题类。
相关设计模式
- 观察者模式通常与单例模式(Singleton Pattern)和工厂方法模式(Factory Method Pattern)结合使用。单例模式用于确保主题对象的唯一性,而工厂方法模式用于创建具体观察者对象。
示例和开源框架中的应用
-
Java中的事件处理:Java中的AWT/Swing GUI库使用了观察者模式来处理事件,例如按钮点击事件。
-
Android中的LiveData:LiveData是Android架构组件之一,它使用了观察者模式来实现数据的生命周期感知和自动更新。
-
Spring框架 - 事件通知:Spring框架中的事件通知机制使用了观察者模式,允许应用程序的不同部分之间以松散耦合的方式通信。
-
消息队列系统:许多消息队列系统(如RabbitMQ和Kafka)使用观察者模式来实现消息的发布和订阅机制。消息生产者充当主题,而消息消费者充当观察者。