Java设计模式之观察者模式:从入门到架构级实践

一、观察者模式的核心价值

观察者模式(Observer Pattern)是行为型设计模式中的经典之作,它建立了对象间的一对多依赖关系,让多个观察者对象能够自动感知被观察对象的状态变化。这种模式在事件驱动系统、实时数据推送、GUI事件处理等场景中广泛应用,是实现松耦合设计的利器。

核心价值体现

  • 解耦生产者(被观察者)与消费者(观察者)

  • 支持动态的观察者注册与注销

  • 实现广播通信机制

  • 符合开放-封闭原则(对扩展开放,对修改关闭)

二、模式结构深度解析

2.1 核心角色分解

  1. Subject(抽象主题)

    • 维护观察者列表(List<Observer>)

    • 提供观察者的注册(attach)和注销(detach)方法

    • 定义通知方法(notifyObservers)

  2. ConcreteSubject(具体主题)

    • 维护具体状态信息

    • 状态改变时调用父类的通知方法

    • 可提供获取状态的接口

  3. Observer(抽象观察者)

    • 定义更新接口(update方法)

  4. ConcreteObserver(具体观察者)

    • 实现具体的更新逻辑

    • 可持有主题引用以获取更多状态信息

2.2 两种通知模型对比

模型类型数据传递方式优点缺点
推模型主题主动推送详细数据给观察者实时性强,响应快可能传递冗余数据
拉模型观察者收到通知后主动拉取数据按需获取,灵活性高增加主题的访问压力

三、基础实现代码示例

3.1 自定义实现版本

// 抽象主题
interface Subject {
    void register(Observer o);
    void remove(Observer o);
    void notifyObservers();
}

// 具体主题(气象站)
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private float temperature;

    public void setMeasurements(float temp) {
        this.temperature = temp;
        notifyObservers();
    }

    @Override
    public void register(Observer o) { observers.add(o); }

    @Override
    public void remove(Observer o) { observers.remove(o); }

    @Override
    public void notifyObservers() {
        for (Observer o : observers) {
            o.update(temperature);
        }
    }
}

// 抽象观察者
interface Observer {
    void update(float temp);
}

// 具体观察者(手机显示)
class PhoneDisplay implements Observer {
    @Override
    public void update(float temp) {
        System.out.println("手机显示温度更新:" + temp + "℃");
    }
}

3.2 Java内置实现

Java自带的java.util.Observable类和Observer接口:

class WeatherData extends Observable {
    private float temperature;

    public void measurementsChanged() {
        setChanged();  // 必须调用此方法
        notifyObservers();
    }

    public void setMeasurements(float temp) {
        this.temperature = temp;
        measurementsChanged();
    }

    // 供观察者拉取数据
    public float getTemperature() {
        return temperature;
    }
}

class TVDisplay implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof WeatherData) {
            WeatherData wd = (WeatherData) o;
            System.out.println("电视显示当前温度:" + wd.getTemperature());
        }
    }
}

四、高级架构实践

4.1 异步观察者模式

ExecutorService executor = Executors.newCachedThreadPool();

class AsyncNotifier {
    public void notifyAsync(List<Observer> observers) {
        observers.forEach(observer -> 
            executor.submit(() -> observer.update())
        );
    }
}

注意事项

  • 线程安全性问题

  • 通知顺序无法保证

  • 异常处理机制

  • 资源释放管理

4.2 基于Java Flow的响应式实现

Java 9+ 引入的响应式流API:

class TemperaturePublisher implements Publisher<Float> {
    private final SubmissionPublisher<Float> publisher = 
        new SubmissionPublisher<>();

    public void publish(float temp) {
        publisher.submit(temp);
    }

    @Override
    public void subscribe(Subscriber<? super Float> subscriber) {
        publisher.subscribe(subscriber);
    }
}

class FlowDisplay implements Subscriber<Float> {
    private Subscription subscription;

    @Override
    public void onSubscribe(Subscription s) {
        this.subscription = s;
        s.request(1);
    }

    @Override
    public void onNext(Float temp) {
        System.out.println("Flow显示温度:" + temp);
        subscription.request(1);
    }
}

五、典型应用场景

5.1 电商订单系统

class OrderService {
    private List<OrderObserver> observers = new CopyOnWriteArrayList<>();

    public void placeOrder(Order order) {
        // 创建订单逻辑...
        notifyObservers(order);
    }

    private void notifyObservers(Order order) {
        observers.forEach(observer -> {
            try {
                observer.onOrderCreated(order);
            } catch (Exception e) {
                // 异常处理
            }
        });
    }
}

interface OrderObserver {
    void onOrderCreated(Order order);
}

// 库存扣减观察者
class InventoryObserver implements OrderObserver {
    @Override
    public void onOrderCreated(Order order) {
        inventoryService.reduceStock(order.getItems());
    }
}

5.2 微服务配置中心

@RestController
public class ConfigController {
    private final ConfigSubject configSubject;

    @PostMapping("/update-config")
    public void updateConfig(@RequestBody Config newConfig) {
        configSubject.updateConfig(newConfig);
    }
}

@Service
class ConfigSubject {
    private List<ConfigObserver> observers = new ArrayList<>();
    private Config currentConfig;

    public synchronized void updateConfig(Config newConfig) {
        this.currentConfig = newConfig;
        notifyObservers();
    }

    private void notifyObservers() {
        observers.forEach(observer -> 
            observer.onConfigChanged(currentConfig)
        );
    }
}

六、生产环境最佳实践

  1. 性能优化策略

    • 采用CopyOnWriteArrayList避免并发修改异常

    • 使用Guava的EventBus进行事件分发

    • 实现观察者优先级机制

    • 添加批处理通知功能

  2. 可靠性增强

    • 引入死信队列处理失败通知

    • 实现幂等性处理

    • 添加事务消息支持

    • 建立监控指标体系(QPS、失败率等)

  3. 扩展性设计

    • 支持观察者过滤器

    • 实现主题分组机制

    • 添加消息持久化能力

    • 支持跨进程观察(分布式观察者)

七、常见陷阱与解决方案

典型问题1:内存泄漏

  • 现象:观察者未及时注销导致无法回收

  • 解决方案:

    // 使用弱引用
    class WeakObserver implements Observer {
        WeakReference<Observer> ref;
    
        public WeakObserver(Observer real) {
            this.ref = new WeakReference<>(real);
        }
    
        // 实现代理方法...
    }

典型问题2:循环通知

  • 现象:A通知B,B又通知A导致死循环

  • 解决方案:

    class SafeSubject implements Subject {
        private boolean notifying = false;
    
        public void notifyObservers() {
            if (notifying) return;
            notifying = true;
            try {
                // 执行通知...
            } finally {
                notifying = false;
            }
        }
    }

典型问题3:性能瓶颈

  • 现象:同步通知大量观察者导致响应延迟

  • 解决方案:

    // 分片异步通知
    List<List<Observer>> shards = partition(observers, 10);
    shards.forEach(shard -> 
        executor.execute(() -> shard.forEach(Observer::update))
    );

八、模式演进与变种

  1. 中介者模式结合

    • 通过中介者统一管理观察关系

    • 实现更复杂的消息路由

  2. 响应式扩展

    • 结合RxJava实现流式处理

    • 支持背压(Backpressure)机制

  3. 领域事件模式

    • 在DDD中应用观察者模式

    • 实现领域事件的发布/订阅

  4. CQRS架构集成

    • 将命令与查询分离

    • 通过观察者维护读模型

九、总结与展望

观察者模式作为解耦利器,在现代架构中展现出强大的生命力。随着响应式编程的兴起,观察者模式正在与以下新技术深度融合:

  1. 云原生架构:跨服务的观察者模式实现

  2. Serverless:事件驱动的函数计算

  3. 物联网(IoT):海量设备的状态同步

  4. 实时数据分析:流式计算中的事件处理

建议开发者根据具体场景选择合适的实现方式:

  • 简单场景:直接使用语言内置支持

  • 复杂系统:采用成熟的响应式框架(如RxJava、Reactor)

  • 分布式环境:使用消息中间件(如Kafka、RabbitMQ)

掌握观察者模式的精髓,将使你的系统架构具备更好的扩展性和灵活性,从容应对各种复杂的业务需求变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听闻风很好吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值