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

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

观察者模式概述

观察者模式(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 自动更新。
  • 消息通知系统:如订单系统中的订单状态变化通知、库存更新通知等。

总结

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

相关推荐
赔罪几秒前
C 语言I/O 函数
c语言·开发语言·数据结构·学习·青少年编程
【上下求索】10 分钟前
学习笔记026——Redis基本操作命令
redis·笔记·学习
垂杨有暮鸦⊙_⊙41 分钟前
阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_作战无人机和察打无人机图鉴
笔记·学习·无人机
数学人学c语言1 小时前
从熟练Python到入门学习C++(record 1)
c++·学习
Petal9909123 小时前
UEFI学习笔记(十八):ARM电源管理之PSCI和SCMI概述
arm开发·笔记·学习·uefi
神秘的土鸡4 小时前
自监督对比学习奠基之作CPC
学习·机器学习
[小瓜]4 小时前
高级AI记录笔记(三)
人工智能·笔记·学习·ue5·虚幻
TPCloud6 小时前
学习rust语言宏之macro_rules!
开发语言·学习·rust·micro_rules
美式小田7 小时前
单片机学习笔记 3. LED灯流水灯
笔记·单片机·嵌入式硬件·学习