从业务场景学习观察者模式

在开发中,当一个对象状态发生变化,需要通知多个其他对象时,观察者模式是一个非常有效的设计模式。通过使用观察者模式,可以在对象间建立一种松散的依赖关系,使得对象在状态变化时,可以通知到其他依赖于它的对象进行相应的更新。本文将以商品库存变化通知的场景为例,带你了解观察者模式的应用。

观察者模式概述

观察者模式(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

代码解读

  1. 被观察者 (Product) :当库存数量通过 setStockQuantity 方法被修改时,会触发 notifyObservers 方法,通知所有观察者更新状态。
  2. 观察者 (Observer) :通过实现 Observer 接口的 update 方法,各观察者可以响应库存变化,更新各自的库存显示。
  3. 松散耦合 :观察者模式让被观察者和观察者之间是松散耦合的,被观察者只知道观察者实现了 Observer 接口,而不关心其具体实现。这种设计提高了代码的可扩展性和可维护性。

观察者模式的优势

  • 松散耦合:观察者和被观察者之间只通过接口依赖,减少了对象之间的耦合度。
  • 扩展性强:可以动态添加或移除观察者,且不影响被观察者的实现。
  • 灵活性:在运行时可以灵活注册和通知观察者。

观察者模式的应用场景

  • 事件系统:在事件驱动编程中,常使用发布-订阅模式来处理事件。
  • MVC 架构:在 MVC 模式中,Model 是被观察者,View 是观察者,当 Model 数据变化时,View 自动更新。
  • 消息通知系统:如订单系统中的订单状态变化通知、库存更新通知等。

总结

观察者模式在应用程序中非常实用,尤其是当对象间的状态依赖关系频繁发生时。本文通过商品库存更新的示例演示了如何实现观察者模式,从而在商品状态变化时及时通知商品详情页和购物车更新显示。这种设计模式让系统更具扩展性和灵活性,是我们在复杂应用中实现模块解耦的有效方式。

相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习