在开发中,当一个对象状态发生变化,需要通知多个其他对象时,观察者模式是一个非常有效的设计模式。通过使用观察者模式,可以在对象间建立一种松散的依赖关系,使得对象在状态变化时,可以通知到其他依赖于它的对象进行相应的更新。本文将以商品库存变化通知的场景为例,带你了解观察者模式的应用。
观察者模式概述
观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象间一对多的依赖关系。当一个对象(即被观察者 或主题 )的状态发生变化时,所有依赖于它的对象(即观察者)都会收到通知并更新。
观察者模式还有以下几个别名:
- 发布-订阅(Publish-Subscribe)模式:被观察者发布消息,观察者订阅消息;
- 模型-视图(Model-View)模式:在 MVC 架构中,Model 的变化通知 View;
- 源-监听(Source-Listener)模式:被观察者作为消息源,观察者作为消息监听者。
业务场景:商品库存变化通知
假设在一个电子商务系统中,有多个模块依赖于商品的库存信息。比如,当商品库存数量发生变化时,我们希望商品详情页和购物车的库存信息也能同步更新,以便向用户展示最新的库存状态。使用观察者模式可以很好地解决这种需求。
在这个场景中:
- 商品库存(Product) 是被观察者;
- 商品详情页(ProductDetailPage) 和 购物车(ShoppingCart) 是观察者,它们需要在商品库存变化时收到通知并更新显示。
实现观察者模式
1. 定义观察者接口
首先,我们定义一个 Observer
接口,包含一个 update
方法。当被观察者状态改变时,这个方法会被调用,更新观察者的状态。
java
// 定义观察者接口
interface Observer {
void update(int stockQuantity); // 更新库存数量的方法
}
2. 定义被观察者类(商品类)
接下来,我们定义商品类 Product
,实现以下功能:
- 维护观察者列表:可以添加、移除观察者;
- 通知观察者:当库存数量发生变化时,通知所有观察者更新库存显示。
java
import java.util.ArrayList;
import java.util.List;
// 定义被观察的商品类(Subject)
class Product {
private List<Observer> observers = new ArrayList<>(); // 观察者列表
private int stockQuantity; // 库存数量
// 添加观察者
public void addObserver(Observer observer) {
observers.add(observer);
}
// 移除观察者
public void removeObserver(Observer observer) {
observers.remove(observer);
}
// 通知所有观察者
private void notifyObservers() {
for (Observer observer : observers) {
observer.update(stockQuantity); // 更新每个观察者
}
}
// 设置库存数量,并通知观察者
public void setStockQuantity(int stockQuantity) {
this.stockQuantity = stockQuantity;
System.out.println("商品库存更新为: " + stockQuantity);
notifyObservers(); // 通知所有观察者
}
}
3. 实现具体观察者(商品详情页和购物车)
现在,我们定义两个具体的观察者类------商品详情页 ProductDetailPage
和购物车 ShoppingCart
,实现 Observer
接口,在库存变化时更新各自的显示信息。
java
// 商品详情页观察者(Concrete Observer)
class ProductDetailPage implements Observer {
@Override
public void update(int stockQuantity) {
System.out.println("商品详情页更新库存显示为: " + stockQuantity);
}
}
// 购物车观察者(Concrete Observer)
class ShoppingCart implements Observer {
@Override
public void update(int stockQuantity) {
System.out.println("购物车更新库存显示为: " + stockQuantity);
}
}
4. 测试观察者模式
最后,我们创建一个测试类 ObserverPatternExample
,验证当商品库存发生变化时,商品详情页和购物车都能收到通知。
java
public class ObserverPatternExample {
public static void main(String[] args) {
// 创建商品(被观察者)
Product product = new Product();
// 创建观察者
ProductDetailPage detailPage = new ProductDetailPage();
ShoppingCart shoppingCart = new ShoppingCart();
// 注册观察者
product.addObserver(detailPage);
product.addObserver(shoppingCart);
// 更新库存数量,触发观察者更新
product.setStockQuantity(10);
product.setStockQuantity(5);
}
}
运行结果
运行代码后,我们可以看到商品库存发生变化时,所有注册的观察者都收到了通知并更新了库存信息。
plaintext
商品库存更新为: 10
商品详情页更新库存显示为: 10
购物车更新库存显示为: 10
商品库存更新为: 5
商品详情页更新库存显示为: 5
购物车更新库存显示为: 5
代码解读
- 被观察者 (
Product
) :当库存数量通过setStockQuantity
方法被修改时,会触发notifyObservers
方法,通知所有观察者更新状态。 - 观察者 (
Observer
) :通过实现Observer
接口的update
方法,各观察者可以响应库存变化,更新各自的库存显示。 - 松散耦合 :观察者模式让被观察者和观察者之间是松散耦合的,被观察者只知道观察者实现了
Observer
接口,而不关心其具体实现。这种设计提高了代码的可扩展性和可维护性。
观察者模式的优势
- 松散耦合:观察者和被观察者之间只通过接口依赖,减少了对象之间的耦合度。
- 扩展性强:可以动态添加或移除观察者,且不影响被观察者的实现。
- 灵活性:在运行时可以灵活注册和通知观察者。
观察者模式的应用场景
- 事件系统:在事件驱动编程中,常使用发布-订阅模式来处理事件。
- MVC 架构:在 MVC 模式中,Model 是被观察者,View 是观察者,当 Model 数据变化时,View 自动更新。
- 消息通知系统:如订单系统中的订单状态变化通知、库存更新通知等。
总结
观察者模式在应用程序中非常实用,尤其是当对象间的状态依赖关系频繁发生时。本文通过商品库存更新的示例演示了如何实现观察者模式,从而在商品状态变化时及时通知商品详情页和购物车更新显示。这种设计模式让系统更具扩展性和灵活性,是我们在复杂应用中实现模块解耦的有效方式。