当前位置: 首页 > news >正文

设计模式 四、行为设计模式(1)

        在设计模式的世界里,23种经典设计模式通常被分为三大类:创建型、结构型和行为型。创建型设计模式关注对象创建的问题,结构性设计模式关注于类或对象的组合和组装的问题,行为型设计模式则主要关注于类或对象之间的交互问题。

        行为设计模式 的数量较多,共有11种,几乎占据了23种经典设计模式的一半。这些模式分别为:观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、访问者模式、备忘录模式、命令模式、解释器模式和中介模式。

一、观察者模式

        1、概述

        观察者模式是一种行为设计模式,允许对象间存在一对多的依赖关系当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新,在这种设计模式种,发生状态改变的对象被称为“主题”(Subject),依赖它的对象成为“观察者”(Observer)。

        观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。在GoF的设计模式书中,它的定义是这样的:

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

        翻译成中文就是说:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

        一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项目开发中,这两种对象的称呼是比较灵活的,有各种不同的叫法,比如:Subject-Observer 、Publisher-Subscriber、Producer-Consumer等等。不管怎么称呼,只要应用场景符合刚刚给出的定义,都可以看作观察者模式。

        简单例子:假设我们有一个气象站,需要向许多不同的显示设备(如手机App、网站、电子屏幕等)提供实施天气数据。

         首先我们创建一个Subject接口,表示主题:

    public interface Subject {
        void registerObserver(Observer o);
        void removeObserver(Observer o);
        void notifyObservers();
    }

        接下来,创建一个Observer接口,表示观察者:

public interface Observer {
    void update(float temperature, float humidity, float pressure);
}

        创建一个具体的主体,如WeatherStation,实现Subject接口:

public class WeatherStation implements Subject {
    private ArrayList<Observer> observers;
    // 温度
    private float temperature;
    // 湿度
    private float humidity;
    // 大气压
    private float pressure;
    public WeatherStation() {
        observers = new ArrayList<>();
    }
    // 注册一个观察者的方法
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    // 移除一个观察者的方法
    @Override
    public void removeObserver(Observer o) {
        int index = observers.indexOf(o);
        if (index >= 0) {
            observers.remove(index);
        }
    }
    // 通知所有的观察者
    @Override
    public void notifyObservers() {
        // 循环所有的观察者,通知其当前的气象信息
        for (Observer o : observers) {
            o.update(temperature, humidity, pressure);
        }
    }
    // 修改气象内容
    public void measurementsChanged() {
        notifyObservers();
    }
    // 当测量值发生了变化的时候
    public void setMeasurements(float temperature, float humidity, float
            pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        // 测量值发生了变化
        measurementsChanged();
    }
}

         最后我们创建一个具体的观察者,如PhoneAPP,实现Observer接口:

public class PhoneApp implements Observer {
    private float temperature;
    private float humidity;
    private float pressure;
    private Subject weatherStation;
    public PhoneApp(Subject weatherStation) {
        this.weatherStation = weatherStation;
        weatherStation.registerObserver(this);
    }
    @Override
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
    }
    public void display() {
        System.out.println("PhoneApp: Temperature: " + temperature + "°C,
                Humidity: " + humidity + "%, Pressure: " + pressure + " hPa");
    }
}

        现在我们可以创建一个WeatherStation实例并向其注册PhoneApp观察者。当WeatherStation的数据发生变化时,PhoneApp会收到通知并更新自己的显示。

public class Main {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();
        PhoneApp phoneApp = new PhoneApp(weatherStation);
        // 模拟气象站数据更新
        weatherStation.setMeasurements(25, 65, 1010);
        weatherStation.setMeasurements(22, 58, 1005);
        // 添加更多观察者 网站上显示-电子大屏
        WebsiteDisplay websiteDisplay = new WebsiteDisplay(weatherStation);
        ElectronicScreen electronicScreen = new ElectronicScreen(weatherStation);
        // 再次模拟气象站数据更新
        weatherStation.setMeasurements(18, 52, 1008);
    }
}

        这个例子中,我们创建了一个WeatherStation实例,并向其注册了PhoneApp、WebsiteDisplay和ElectronicScreen观察者,当WeatherStation的数据发生变化这个例子展示了观察者模式的优点:
        1)观察者和主题之间解耦:主题只需要知道观察者实现了Observer接口,而无需了解具体的实现细节。
        2)可以动态的添加和删除观察者:通过调用registerObserver 和 removeObserver方法,可以在运行时添加和删除观察者。
        3)主题和观察者之间的通信时自动的:当主题的状态发生变化时,观察者会自动得到通知并更新自己的状态。

        观察者广泛应用于各种场景,例如事件处理系统、数据同步和更新通知等。上面例子算是观察者模式的 “模板代码”,可以反应该模式大体得设计思路,在真实得软件开发中,并不需要照搬相面的模板代码。观察者模式的实现方法各式各样, 函数、类的命名等会根据业务场景的不同有很大的差别,比如 register 函数还可以 叫作 attachremove 函数还可以叫作 detach 等等。不过,万变不离其宗,设计思 路都是差不多的。

        了解了观察者设计模式的基本使用方式,我们接下来看看他的具体使用场景

相关文章:

  • 基于层次建模与交叉注意力融合的医学视觉问答系统(HiCA-VQA)详解
  • ⑨数据中心-M-LAG技术配置
  • 8.1 公共控件12
  • 【学Rust写CAD】35 alpha_mul_256(alpha256.rs补充方法)
  • Mamba模型
  • 21 天 Python 计划:MySQL 表相关操作
  • #node.js后端项目的部署相关了解
  • 蓝桥杯每日刷题c++
  • 第4课:多智能体通信协议优化
  • 【区块链安全 | 第三十二篇】内联汇编
  • 13. C++入门基础***
  • 数据库架构
  • 双指针(5)—复写零
  • 层归一化详解及在 Stable Diffusion 中的应用分析
  • AI烘焙大赛中的算法:理解PPO、GRPO与DPO最简单的方式
  • 类和对象(下篇)(详解)
  • nginx中的try_files指令
  • UML组件图
  • 2025年前端框架全景解析:React、Vue、Angular的生态与未来之争
  • 南柯电子|EMC电磁兼容性摸底检测测试整改:技术挑战与解决方案
  • wordpress建站时间/推广页面制作
  • 好看企业官网源码/关键词seo优化排名
  • 网站制作价格多少钱/seo检测优化
  • 网站开发计入什么费用/软文形式推广产品
  • 景点网站怎么做/seo网站快速排名
  • 谷歌网站建设/博客推广工具