2025/10/17日 每日总结 设计模式实践:观察者模式之股票价格提醒案例解析

设计模式实践:观察者模式之股票价格提醒案例解析

在软件开发中,经常需要处理“一个对象状态变化,多个相关对象需同步响应”的场景。观察者模式通过定义“被观察者-观察者”的一对多依赖关系,让被观察者状态变化时自动通知所有观察者,实现状态同步与解耦。本文将通过股票价格涨跌提醒的实际场景,详细拆解观察者模式的实现逻辑与应用价值。

一、实验背景与需求

本次实践的核心需求是实现股票价格变动提醒系统,具体规则如下:

  1. 被观察者(股票):价格上涨或下跌5%时,自动通知所有关注它的观察者(股民)

  2. 观察者(股民):收到价格上涨通知时执行“买股票”操作,收到价格下跌通知时执行“大哭一场”操作

  3. 支持动态添加/移除观察者(股民可随时关注/取消关注股票)

  4. 被观察者与观察者解耦,互不直接依赖

二、观察者模式核心结构

观察者模式的关键在于“被观察者”维护观察者列表并提供通知接口,“观察者”实现响应接口,接收通知后执行对应逻辑。本次案例的结构设计如下:

1. 核心组件划分

组件类型 具体实现 职责描述
抽象观察者(Observer) Observer 接口 定义观察者的响应接口(价格上涨/下跌时的行为)
具体观察者(ConcreteObserver) Investor 类(股民) 实现抽象观察者接口,具体实现“买股票”和“大哭”逻辑
抽象被观察者(Subject) Subject 抽象类 定义被观察者的核心接口(添加/移除观察者、通知观察者),维护观察者列表
具体被观察者(ConcreteSubject) Stock 类(股票) 实现抽象被观察者接口,触发价格变动时通知所有观察者

2. 类图结构

┌─────────────────┐
│ Observer │ ← 抽象观察者(股民接口)
├─────────────────┤
│ + buy(): void │ ← 价格上涨时的响应
│ + cry(): void │ ← 价格下跌时的响应
└─────────────────┘
▲
│
┌───────────────┐
│ Investor │ ← 具体观察者(股民)
├───────────────┤
│ + buy(): void │ → 实现“买股票”逻辑
│ + cry(): void │ → 实现“大哭一场”逻辑
└───────────────┘
┌─────────────────┐
│ Subject │ ← 抽象被观察者(股票接口)
├─────────────────┤
│ - observers: List<Observer> │ ← 维护观察者列表
├─────────────────┤
│ + abstract attach(observer: Observer): void │ ← 添加观察者(关注股票)
│ + abstract detach(observer: Observer): void │ ← 移除观察者(取消关注)
│ + abstract up(): void │ ← 价格上涨时通知观察者
│ + abstract down(): void │ ← 价格下跌时通知观察者
└─────────────────┘
▲
│
┌───────────────┐
│ Stock │ ← 具体被观察者(股票)
├───────────────┤
│ + attach(observer: Observer): void │ → 实现添加观察者
│ + detach(observer: Observer): void │ → 实现移除观察者
│ + up(): void │ → 价格上涨,通知所有观察者执行buy()
│ + down(): void │ → 价格下跌,通知所有观察者执行cry()
└───────────────┘

三、完整实现代码(Java)

1. 抽象观察者:Observer.java

/**
* 抽象观察者接口:定义股民的响应行为
*/
public interface Observer {
// 股票上涨时的响应:买股票
void buy();

// 股票下跌时的响应:大哭一场
void cry();
}

### 2. 抽象被观察者:Subject.java
```java
import java.util.ArrayList;
/**
 * 抽象被观察者类:定义股票的核心接口
 */
public abstract class Subject {
 // 维护关注当前股票的观察者列表
 protected ArrayList<Observer> observers = new ArrayList<>();

// 添加观察者(股民关注股票)
 public abstract void attach(Observer observer);

// 移除观察者(股民取消关注股票)
 public abstract void detach(Observer observer);

// 股票价格上涨,通知所有观察者
 public abstract void up();

// 股票价格下跌,通知所有观察者
 public abstract void down();
}

3. 具体观察者:Investor.java

/**
 * 具体观察者类:股民,实现响应逻辑
 */
public class Investor implements Observer {
 @Override
 public void buy() {
 System.out.println("股票价格上涨5%,股民买股票");
 }

@Override
 public void cry() {
 System.out.println("股票价格下降5%,股民大哭一场");
 }
}

4. 具体被观察者:Stock.java

/**
 * 具体被观察者类:股票,实现通知逻辑
 */
public class Stock extends Subject {
 // 添加观察者(股民关注股票)
 @Override
 public void attach(Observer observer) {
 observers.add(observer);
 }

// 移除观察者(股民取消关注股票)
 @Override
 public void detach(Observer observer) {
 observers.remove(observer);
 }

// 股票上涨,通知所有观察者执行买股票操作
 @Override
 public void up() {
 for (Object obj : observers) {
 ((Observer) obj).buy();
 }
 }

// 股票下跌,通知所有观察者执行大哭操作
 @Override
 public void down() {
 for (Object obs : observers) {
 ((Observer) obs).cry();
 }
 }
}

5. 客户端测试类:Client.java

/**
 * 测试类:验证股票价格变动通知功能
 */
public class Client {
 public static void main(String[] args) {
 // 1. 创建观察者(两位股民)
 Observer investor1 = new Investor();
 Observer investor2 = new Investor();

// 2. 创建被观察者(股票)
 Subject stock = new Stock();

// 3. 股民关注股票(添加观察者)
 stock.attach(investor1);
 stock.attach(investor2);

// 4. 股票价格上涨5%,触发通知
 System.out.println("=== 股票价格上涨5% ===");
 stock.up();

// 5. 股票价格下跌5%,触发通知
 System.out.println("\n=== 股票价格下跌5% ===");
 stock.down();

// 6. 测试移除观察者(股民2取消关注)
 System.out.println("\n=== 股民2取消关注股票 ===");
 stock.detach(investor2);

// 7. 再次触发价格上涨
 System.out.println("=== 股票价格再次上涨5% ===");
 stock.up();
 }
}

四、运行结果

=== 股票价格上涨5% ===
股票价格上涨5%,股民买股票
股票价格上涨5%,股民买股票
=== 股票价格下跌5% ===
股票价格下降5%,股民大哭一场
股票价格下降5%,股民大哭一场
=== 股民2取消关注股票 ===
=== 股票价格再次上涨5% ===
股票价格上涨5%,股民买股票

从运行结果可以看出:

  1. 两位股民同时关注股票时,价格变动会通知所有观察者

  2. 股民2取消关注后,仅剩余观察者(股民1)收到通知

  3. 被观察者与观察者解耦,股票无需知道股民具体身份,仅通过接口通知

五、观察者模式核心优势与特性

1. 核心优势

  • 解耦被观察者与观察者:两者通过抽象接口交互,互不依赖具体实现,便于单独扩展

  • 动态订阅/取消:支持观察者随时添加/移除,灵活性高(如股民随时关注/取消关注股票)

  • 广播通知:被观察者状态变化时,自动通知所有观察者,无需手动调用

  • 符合开闭原则:新增观察者时无需修改被观察者代码,仅需实现抽象观察者接口

    2. 适用场景与注意事项

    适用场景

  • 一个对象状态变化需同步更新多个对象(如股票提醒、消息通知、数据监控)

  • 需动态维护“订阅-通知”关系(如公众号关注、邮件订阅)

  • 希望减少对象间直接耦合,提高系统可维护性

    注意事项

  • 避免循环依赖:观察者状态变化不应反向触发被观察者状态变化,否则会导致无限循环

  • 控制通知顺序:默认按添加顺序通知观察者,若需指定顺序需额外处理

  • 性能考虑:观察者过多时,通知可能耗时,可考虑异步通知或分批通知

    六、总结

    通过本次股票价格提醒的实践案例,深刻体会到观察者模式在“状态同步”场景中的核心价值。它将“被观察者状态变化”与“观察者响应”解耦,让系统结构更清晰、扩展性更强,避免了对象间的直接耦合。
    在实际开发中,观察者模式的应用非常广泛:如GUI开发中的按钮点击事件监听、分布式系统中的消息通知、电商平台的订单状态变更通知(用户、商家、物流同步响应)等。合理运用观察者模式,能有效提升系统的灵活性和可维护性。

posted @ 2025-12-29 14:39  Moonbeamsc  阅读(28)  评论(0)    收藏  举报
返回顶端