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

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日

相关文章

  • Vue中router-link如何添加mouseover提示

    要在Vue中使用mouseover提示,我们可以使用title属性。而对于router-link组件,要使用mouseover提示,我们可以在组件内部使用slot来传递title属性。 以下是添加mouseover提示的步骤: 在router-link标签内部使用slot,传递属性title,如下所示: <router-link to="/&…

    JavaScript 2023年6月11日
    00
  • 服务器端C#实现的CSS解析器

    服务器端C#实现的CSS解析器攻略 简介 服务器端C#实现的CSS解析器可以帮助我们在服务器端解析CSS文件,方便我们对于CSS文件进行修改、分析、压缩以及提取样式等操作。在本篇攻略中,我们将会讲解如何使用C#实现CSS解析器,以及其中的两个示例应用。 实现步骤 以下是使用C#实现CSS解析器的步骤: 安装NuGet包“CssParser”,该NuGet包是…

    JavaScript 2023年5月28日
    00
  • 详解设置Webstorm 利用babel将ES6自动转码成ES5

    下面是详细讲解“详解设置Webstorm 利用babel将ES6自动转码成ES5”的完整攻略: 1. 安装和配置Babel 首先需要安装Babel,并通过npm安装相关的转码插件。在终端命令行中输入以下两行命令: npm install –save-dev babel-cli babel-preset-env npm install babel-plugi…

    JavaScript 2023年6月11日
    00
  • 用JavaScript获取DOM元素位置和尺寸大小的方法

    获取DOM元素位置和尺寸大小对于前端开发来说非常重要,这篇文章将向你介绍使用JavaScript获取DOM元素位置和尺寸大小的方法。 获取DOM元素位置 getBoundingClientRect()方法 使用HTMLElement对象的getBoundingClientRect()方法可以获取一个元素相对于视口的位置和尺寸。该方法返回一个DOMRect对象…

    JavaScript 2023年6月10日
    00
  • 利用Js的console对象,在控制台打印调式信息测试Js的实现

    利用Js的console对象,在控制台打印调试信息是Web开发中非常常见的一种调试方式。下面是一些步骤: 1. 开启浏览器的开发者工具 首先,我们需要在浏览器中打开一个网站,然后按下键盘上的F12键,或者通过右键打开菜单选择“检查”选项来打开浏览器的开发者工具。 2. 在Js代码中添加console调试信息 为了方便调试,我们在Js代码中添加console输…

    JavaScript 2023年5月28日
    00
  • JavaScript Date 对象

    以下是关于JavaScript Date对象的完整攻略。 JavaScript Date对象 JavaScript Date对象用于处理日期和时间。它可以存储从1970年1月1日00:00:00 UTC协调世界时)开始的毫秒数,并提供了一组方法来处理日期和时间。 下面是一个使用Date对象的示例: var now = new Date(); console.…

    JavaScript 2023年5月11日
    00
  • JS window对象简单操作完整示例

    好的!下面我将为您提供一份详细的“JS window对象简单操作完整示例”的攻略。 什么是window对象 window 对象是客户端 JavaScript 的全局对象,也可以说是浏览器窗口或框架的 JavaScript 接口。每个打开的窗口都包含一个 window 对象。在网页中,可以使用 window 对象来操纵浏览器的行为,比如改变浏览器的大小,跳转到…

    JavaScript 2023年5月27日
    00
  • JavaScript事件处理的方式(三种)

    JavaScript事件处理的方式,一般可以分为三种,分别是通过HTML属性、DOM 0级事件处理和DOM 2级事件处理。下面将一一详细讲解。 1. HTML属性方式 使用HTML标签的事件属性来绑定事件,比如<button onclick=”alert(‘clicked’)”>Click me</button>。 HTML属性事件处…

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