Java设计模式之观察者模式_动力节点Java学院整理

yizhihongxing

Java设计模式之观察者模式

1. 什么是观察者模式

观察者模式是一种行为型设计模式,它允许一个或多个对象在状态发生改变时自动通知其他对象。

在观察者模式中,存在两种角色:

  • Subject(目标):负责发布通知的角色,可以添加,删除观察者,并通知观察者状态的变化。
  • Observer(观察者):当被观察的对象的状态发生变化时,它会自动接收到通知并进行相应的处理。

2. 观察者模式的优缺点

优点

  • 解耦。观察者模式可以使观察者和目标之间解耦,目标只关心自己的状态变化,而不需要了解观察者的情况。
  • 可扩展。可以增加观察者和目标的数量,而不需要改变他们的代码。
  • 一致性。观察者模式使得目标和观察者之间保持一致性,因为观察者可以按照目标的数据结构重新构造自己的状态。
  • 开闭原则。新的观察者可以被加入到系统中,而不需要修改原有的代码。

缺点

  • 观察者过多会导致系统效率降低。
  • 如果目标跟观察者耦合度过高,会导致目标的变化会带来额外的消息量。

3. 示例说明

示例一:新闻发布

Subject:发布新闻的机构,可以添加,删除观察者,并在有新闻时通知所有已注册的观察者。

public class NewsPublisher {
    private List<NewsSubscriber> subscribers = new ArrayList<>();

    public void subscribe(NewsSubscriber subscriber) {
        subscribers.add(subscriber);
    }

    public void unsubscribe(NewsSubscriber subscriber) {
        subscribers.remove(subscriber);
    }

    public void publishNews(String news) {
        System.out.println("新闻发布:" + news);
        // 通知所有观察者
        for (NewsSubscriber subscriber : subscribers) {
            subscriber.update(news);
        }
    }
}

Observer:新闻订阅者,可以接收发布机构发布的新闻。

public class NewsSubscriber {
    private String name;

    public NewsSubscriber(String name) {
        this.name = name;
    }

    public void update(String news) {
        System.out.println(name + " 收到新闻:" + news);
    }
}

测试方法:

 NewsPublisher publisher = new NewsPublisher();
 NewsSubscriber s1 = new NewsSubscriber("小明");
 NewsSubscriber s2 = new NewsSubscriber("小红");
 publisher.subscribe(s1);
 publisher.subscribe(s2);
 publisher.publishNews("今天天气晴朗,适合外出旅游");
 publisher.unsubscribe(s1);
 publisher.publishNews("下雨了,注意交通安全");

输出结果:

新闻发布:今天天气晴朗,适合外出旅游
小明 收到新闻:今天天气晴朗,适合外出旅游
小红 收到新闻:今天天气晴朗,适合外出旅游
新闻发布:下雨了,注意交通安全
小红 收到新闻:下雨了,注意交通安全

可以看到,两个新闻订阅者都收到了发布机构发布的新闻,当有订阅者取消订阅后也不会再收到通知。

示例二:气象站

Subject:气象站,可以添加,删除观察者,并在气象数据更新时通知所有已注册的观察者。

public class WeatherStation {
    private List<WeatherObserver> observers = new ArrayList<>();
    private float temperature;
    private float humidity;
    private float pressure;

    public void registerObserver(WeatherObserver observer) {
        observers.add(observer);
    }

    public void removeObserver(WeatherObserver observer) {
        observers.remove(observer);
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

    private void notifyObservers() {
        for (WeatherObserver observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }
}

Observer:气象数据展示面板,可以接收气象站的更新数据并显示。

public class WeatherDisplay implements WeatherObserver {
    private float temperature;
    private float humidity;
    private float pressure;

    @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("当前气象数据:温度 " + temperature + " °C,湿度 " + humidity + "%,气压 " + pressure + " Pa");
    }
}

测试方法:

WeatherStation station = new WeatherStation();
WeatherObserver observer1 = new WeatherDisplay();
WeatherObserver observer2 = new WeatherDisplay();
station.registerObserver(observer1);
station.registerObserver(observer2);
station.setMeasurements(25f, 50f, 100f);
station.setMeasurements(30f, 60f, 120f);
station.removeObserver(observer2);
station.setMeasurements(35f, 70f, 140f);

输出结果:

当前气象数据:温度 25.0 °C,湿度 50.0%,气压 100.0 Pa
当前气象数据:温度 30.0 °C,湿度 60.0%,气压 120.0 Pa
当前气象数据:温度 35.0 °C,湿度 70.0%,气压 140.0 Pa

可以看到,两个气象数据面板都显示出了气象站更新的数据,当有展示面板取消观察后也不再收到通知。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之观察者模式_动力节点Java学院整理 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结

    为了实现找出5个数中最大的一个数和倒数第二大的数,可以采用以下三种方法: 1.使用排序函数 代码示例: let arr = [1,2,3,4,5]; arr.sort(function(a, b){return b-a}); console.log(arr[0]); console.log(arr[1]); 说明:该方法通过 JavaScript 的 sor…

    JavaScript 2023年5月28日
    00
  • 基于element-ui 动态换肤的代码详解

    基于element-ui动态换肤的代码详解,其实主要是通过更改CSS样式来实现主题颜色的更换。 首先,我们需要借助element-ui提供的主题生成工具element-theme来生成我们需要的主题样式文件。 生成主题样式文件的具体步骤如下: 全局安装element-theme: npm install element-theme -g 在项目目录下新建th…

    JavaScript 2023年6月10日
    00
  • JS中2种定时器的使用及清除的实现

    JS中有两种定时器,分别是setInterval()和setTimeout(),这两种定时器都有其特殊的用处。下面我将为你详细讲解这两种定时器的使用方法和如何清除定时器。 setInterval()定时器 setInterval() 根据指定的周期(以毫秒为单位)来调度一个函数,函数会按照指定的周期被周期性地执行。setInterval函数接受两个参数——第…

    JavaScript 2023年6月11日
    00
  • js面向对象编程OOP及函数式编程FP区别

    一、OOP与FP概述 OOP(Object-oriented Programming)即面向对象编程,是一种编程范式,通过抽象出类来描述对象及其行为,并通过类的继承将代码组织成复杂的对象体系结构,从而使代码更加易于维护与扩展。 FP(Functional Programming)即函数式编程,是一种编程范式,重点在于函数,它将计算过程视为一系列的函数求值,通…

    JavaScript 2023年5月27日
    00
  • 理解JSON:3分钟课程

    理解JSON:3分钟课程 什么是JSON? JSON(JavaScript Object Notation),是一种轻量级的数据交换格式。它基于JavaScript的语法,但也可以用于其他编程语言。 JSON的基本结构 JSON由键值对构成,在键和值之间使用冒号来表示关联关系,每组键值对之间使用逗号来分隔。JSON的整体结构可以是一个对象或一个数组。 对象 …

    JavaScript 2023年5月27日
    00
  • JavaScript奇技淫巧44招【实用】

    JavaScript奇技淫巧44招【实用】攻略 作为一名网站开发者,熟练掌握JavaScript的技巧和小技巧是非常重要的。下面是44个实用的JavaScript奇技淫巧,以及它们的用法和示例说明。 1. 使用逻辑运算符和函数默认值进行简化 function multiply(a, b) { b = typeof b !== ‘undefined’ ? b …

    JavaScript 2023年5月18日
    00
  • JavaScript接口实现代码 (Interfaces In JavaScript)

    JavaScript在ES6之前并没有真正的接口(Interfaces)的概念,但是我们可以通过一些技巧来实现接口。在这篇文章中,我将为你呈现一个完整的JavaScript接口实现代码攻略: 什么是JavaScript接口? 接口是一个描述类应该如何实现函数的集合。在函数式编程中,接口是一个纯粹的抽象概念,用于描述具有特定行为或功能的组件。 如何实现Java…

    JavaScript 2023年5月18日
    00
  • javascript不同类型数据之间的运算的转换方法

    下面是关于 JavaScript 不同类型数据之间的运算的转换方法的攻略: 类型转换 JavaScript 是一种弱类型语言,允许不同类型之间的运算。但是,不同的类型进行运算时会出现意想不到的结果。为了确保正确的运算结果,我们需要将不同类型的数据转换成相同的类型。 JavaScript 提供了三种类型转换方法: 转换为字符串 转换为数值 转换为布尔值 转换为…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部