作者主页:Designer 小郑 作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN博客专家,阿里云社区专家博主,蓝桥云课讲师。
一、什么是观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,它建立了一种一对多的依赖关系,让多个观察者对象同时监听一个被观察者对象的状态变化,当被观察者对象的状态发生变化时,会自动通知所有观察者对象进行相应的更新操作。
观察者模式也被称为发布-订阅(Publish-Subscribe)模式。
在观察者模式中,有
个核心角色。
- Subject(被观察者):它是一个抽象类或接口,定义了被观察者对象的基本操作,包括添加、删除和通知观察者的方法。
- ConcreteSubject(具体被观察者):它是被观察者的具体实现,维护被观察者的状态,并在状态发生变化时通知所有观察者。
- Observer(观察者):它是一个抽象类或接口,定义了观察者对象的基本操作,包括更新方法。
- ConcreteObserver(具体观察者):它是观察者的具体实现,实现了观察者的更新方法,以便在接收到被观察者的通知时进行相应的操作。
观察者模式的核心思想是将观察者和被观察者解耦,使它们之间的依赖关系松散,从而实现对象间的松耦合。观察者模式能够在不改变被观察者和观察者之间的代码的情况下,动态地添加和删除观察者,从而提高了系统的灵活性和可扩展性。它常被用于事件处理、消息推送、GUI编程等场景。
二、观察者模式实例
代码语言:javascript复制下面是一个简单的 Java 代码示例,演示了观察者模式的实现,请同学们复制到本地执行。
import java.util.ArrayList;
import java.util.List;
// 被观察者接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体的被观察者
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String message;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(message);
}
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
}
// 观察者接口
interface Observer {
void update(String message);
}
// 具体的观察者
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name " 收到消息:" message);
}
}
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver("观察者1");
ConcreteObserver observer2 = new ConcreteObserver("观察者2");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setMessage("Hello World!");
subject.removeObserver(observer1);
subject.setMessage("How are you?");
}
}
在上述示例中,ConcreteSubject
是具体的被观察者,实现了 Subject
接口,它维护了一个观察者列表,并实现了注册、删除和通知观察者的方法。
ConcreteObserver
是具体的观察者,实现了Observer
接口。它定义了更新方法,当收到被观察者的通知时,会执行相应的操作。
在 ObserverPatternDemo
类中,我们创建了一个具体的被观察者对象 subject
,以及两个具体的观察者对象 observer1
和 observer2
。我们通过调用 registerObserver
方法将观察者添加到被观察者的列表中。然后,我们调用 setMessage
方法来设置被观察者的消息,从而触发通知操作。
最后,我们通过调用 removeObserver
方法将一个观察者从被观察者的列表中移除,再次调用 setMessage
方法来触发通知操作。运行代码,可以看到观察者收到了相应的消息。
三、观察者模式的应用场景
观察者模式在许多应用程序中都有广泛的应用,以下是观察者模式常见的应用场景,请同学们认真学习。
- GUI编程:在图形用户界面中,常常使用观察者模式来监听用户界面的交互事件,例如按钮的点击、菜单的选择等。当事件发生时,观察者会被通知并执行相应的操作,从而实现用户界面和业务逻辑的解耦。
- 消息推送系统:观察者模式常被用于实现消息推送系统。当有新消息产生时,被观察者会通知所有的观察者,以便它们能够及时接收到新消息并进行相应的处理。
- 订阅-发布模式:订阅-发布模式是观察者模式的一种扩展,常用于事件驱动的系统中。订阅者通过订阅感兴趣的事件,当事件发生时,发布者会通知所有订阅者,使它们能够响应相应的事件。
- 数据库触发器:当数据库中的数据发生改变时,触发器可以通知相关的观察者进行相应的操作。观察者可以是其他数据库,或者是应用程序中的其他模块,以实现数据的同步和一致性。
- 股票交易系统:在股票交易系统中,经纪人和投资者之间的关系可以使用观察者模式来建模。当股票价格发生变化时,经纪人会通知所有的投资者,以便他们能够及时作出相应的决策。
观察者模式适用于当一个对象的改变需要通知其他多个对象时,同时观察者对象之间应尽量保持独立,以减少耦合性。
四、观察者模式面试题
- 什么是观察者模式?它解决了什么问题?
- 观察者模式的核心角色有哪些?
- 观察者模式和发布-订阅模式有何区别?
- 观察者模式如何实现对象之间的解耦?
- 观察者模式的优点是什么?
- 观察者模式的缺点是什么?
- 如何实现一个简单的观察者模式?
- 观察者模式在哪些场景下应用较为常见?
- 如何防止观察者模式中的内存泄漏问题?
- 观察者模式和回调函数有何异同?