【设计模式】用Java实现观察者模式

简介: 观察者模式是一种行为设计模式,用于实现对象之间的发布-订阅机制。在该模式中,存在一个主题对象(被观察者),它维护了一个观察者列表,并在自身状态发生改变时通知所有观察者。观察者对象订阅主题对象的状态变化,并在收到通知后执行相应的操作。

一.观察者模式介绍与使用场景


观察者模式是一种行为设计模式,用于实现对象之间的发布-订阅机制。在该模式中,存在一个主题对象(被观察者),它维护了一个观察者列表,并在自身状态发生改变时通知所有观察者。观察者对象订阅主题对象的状态变化,并在收到通知后执行相应的操作。


观察者模式通常由以下几个角色组成:


主题(Subject):主题是被观察的对象,它维护了一组观察者,并提供了用于添加、删除和通知观察者的方法。

观察者(Observer):观察者是订阅主题对象的对象,它定义了接收通知和执行相应操作的方法。

观察者模式的核心思想是将主题和观察者解耦,使得它们可以独立变化。主题对象在状态发生变化时,会自动通知观察者对象,而无需观察者主动轮询状态变化。


使用场景:

当一个对象的状态变化需要通知其他对象,并且不希望主动耦合到这些对象时,观察者模式非常有用。通过将观察者注册到主题对象,主题对象在状态变化时会自动通知观察者,而无需观察者主动轮询状态变化。


当一个对象的状态变化可能会引起其他多个对象的更新或处理时,观察者模式可以帮助我们实现对象间的解耦。观察者模式使得主题对象和观察者对象之间的关系变得灵活,可以随时添加、移除或替换观察者,而不影响其他对象的行为。当系统中存在一对多的依赖关系,一个对象的变化需要通知多个对象时,观察者模式能够提供一种简单且可扩展的设计方案。主题对象充当发布者,而观察者对象充当订阅者,它们之间形成了一种松耦合的发布-订阅机制。
当需要在不同层级或模块之间进行消息传递和事件处理时,观察者模式可以帮助我们实现这种通信机制。主题对象作为事件源,观察者对象作为事件处理者,它们之间通过事件通知进行交互。


总结,观察者模式适用于以下情况:

  • 一个对象的状态变化需要通知其他对象,并且不希望主动耦合到这些对象。
  • 一个对象的状态变化可能会引起其他多个对象的更新或处理。
  • 系统中存在一对多的依赖关系,一个对象的变化需要通知多个对象。
  • 需要在不同层级或模块之间进行消息传递和事件处理。

通过使用观察者模式,我们可以实现对象间的解耦,提高系统的可维护性和扩展性。同时,观察者模式也符合开闭原则,因为可以动态添加和移除观察者,而无需修改主题对象的代码。


二.观察者模式实现


下面我们用一个简单的demo来描述一下观察者模式:

import java.util.ArrayList;
import java.util.List;
// 主题 - 被观察者
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
// 具体主题 - 商品
class Product implements Subject {
    private List<Observer> observers;
    private String name;
    public Product(String name) {
        this.observers = new ArrayList<>();
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
        notifyObservers();
    }
    public String getName() {
        return name;
    }
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
}
// 观察者
interface Observer {
    void update(Subject subject);
}
// 具体观察者 - 用户
class User implements Observer {
    private String name;
    public User(String name) {
        this.name = name;
    }
    public void update(Subject subject) {
        if (subject instanceof Product) {
            Product product = (Product) subject;
            System.out.println(name + " received a notification: " + product.getName() + " is now available.");
        }
    }
}
// 使用示例
public class Main {
    public static void main(String[] args) {
        // 创建主题对象
        Product product = new Product("iPhone 13");
        // 创建观察者对象
        User user1 = new User("John");
        User user2 = new User("Alice");
        // 注册观察者
        product.registerObserver(user1);
        product.registerObserver(user2);
        // 修改主题状态并通知观察者
        product.setName("iPhone 14");
    }
}

在上述示例中,我们模拟了一个商品发布订阅的场景。主题对象 Product 是被观察的对象,用户对象 User 是观察者。当商品名称发生变化时,主题对象会通知所有观察者对象。


通过 Subject 接口,主题对象提供了注册、移除和通知观察者的方法。具体主题类 Product 实现了主题接口,并维护了观察者列表。在商品名称发生变化时,它会调用 notifyObservers() 方法,遍历观察者列表并调用观察者的 update() 方法。


观察者类 User 实现了观察者接口,并定义了收到通知后的具体操作。在 Main 类的 main 方法中,我们创建了一个商品对象和两个用户对象,并注册用户对象为观察者。当商品名称变化时,观察者会收到通知并执行相应的操作。


通过使用观察者模式,我们能够实现对象之间的松耦合关系,使得主题对象和观察者对象可以独立变化。主题对象无需关心具体的观察者,只需通知它们即可。同时,观察者模式也使得我们能够轻松地添加、移除和管理观察者,以满足动态变化的需求。


相关文章
|
6天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
2天前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
6天前
|
设计模式 Java 关系型数据库
设计模式——观察者模式
观察者模式介绍、观察者模式优化天气预报案例、JDK 的Observable类和Observer类
设计模式——观察者模式
|
6天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
6天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
21天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
37 2
|
21天前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
30 1
|
21天前
|
设计模式 Java
重构你的代码:探索Java中的混合、装饰器与组合设计模式
【8月更文挑战第30天】在软件开发中,设计模式为特定问题提供了结构化的解决方案,使代码更易理解、维护及扩展。本文将介绍三种常用的 Java 设计模式:混合模式、装饰器模式与组合模式,并附有示例代码展示实际应用。混合模式允许通过继承多个接口或抽象类实现多重继承;装饰器模式可在不改变对象结构的情况下动态添加新功能;组合模式则通过树形结构表示部分-整体层次,确保客户端处理单个对象与组合对象时具有一致性。
15 1
|
Java
JAVA内置的观察者模式样本
DisplayElement.java public interface DisplayElement { public void display(); } CurrentConditionsDisplay.
681 0
|
6天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)