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日

相关文章

  • js 声明数组和向数组中添加对象变量的简单实例

    下面是关于JS声明数组和向数组中添加对象变量的简单实例的完整攻略。 一、JS声明数组 在JS中声明数组可以使用Array关键字或简单的方括号[]来完成,比如: // 使用Array关键字声明 let arr1 = new Array(); // 简单使用方括号声明 let arr2 = []; 以上两种声明方式是等价的。 二、向数组中添加对象变量 要向JS数…

    JavaScript 2023年5月27日
    00
  • javascript运动效果实例总结(放大缩小、滑动淡入、滚动)

    下面是 “javascript运动效果实例总结(放大缩小、滑动淡入、滚动)” 的详细攻略: 1. 放大缩小实例 该实例可以通过javascript实现图片的放大和缩小,具体思路如下: 1.1 给图片添加鼠标事件 在html中给需要放大缩小的图片添加mouseenter事件: <img src="picture.jpg" id=&qu…

    JavaScript 2023年6月11日
    00
  • javascript中String类的subString()方法和slice()方法

    当我们需要对字符串进行裁剪或切片操作时,JavaScript中的String类提供了两个常用的方法:substring()和slice()。这两种方法都能够将一个字符串切分为多个子串,但它们有一些不同之处。 substring()方法 substring()方法用于将字符串中的一部分截取出来,返回一个新的字符串。其接受两个参数,分别代表子字符串的起始位置和终…

    JavaScript 2023年5月28日
    00
  • JavaScript高级程序设计(第3版)学习笔记12 js正则表达式

    下面是详细的攻略: JavaScript高级程序设计(第3版)学习笔记12 js正则表达式 简介 本篇学习笔记介绍JavaScript正则表达式的基础知识,包括正则表达式的定义、创建、元字符、模式修饰符、贪婪与非贪婪匹配、匹配位置等知识点。 正则表达式的定义 正则表达式是一种用来匹配字符串模式的方法,它由一个或多个字符和特殊字符组成,表示一种模式,用于与字符…

    JavaScript 2023年6月10日
    00
  • javascript字符串替换及字符串分割示例代码

    下面就是关于“javascript字符串替换及字符串分割”的完整攻略。 JavaScript 字符串替换 在 JavaScript 中,可以使用 replace() 方法实现字符串替换功能。该方法接收两个参数,第一个参数是要替换的字符串或正则表达式,第二个参数是新的字符串。 下面是一个简单的示例,代码如下: let str = "hello Jav…

    JavaScript 2023年5月28日
    00
  • countUp.js实现数字滚动效果

    下面我将详细讲解“countUp.js实现数字滚动效果”的完整攻略。 什么是countUp.js countUp.js是一个轻量级的JavaScript库,它可以帮助开发者实现数字滚动效果,使数字以动画的形式逐步增加到目标值。 应用场景 countUp.js常用于数字计数器、数据统计、商品价格展示等需要数字动态变化的场景。 使用方法 步骤一:引入countU…

    JavaScript 2023年6月11日
    00
  • JavaScript实现网页电子时钟

    下面是JavaScript实现网页电子时钟的完整攻略: 1. 创建HTML结构 在HTML中,我们需要创建与时钟相关的结构,通常是一个div容器,里面包含用于显示时间的三个子容器(小时、分钟、秒钟)。 <div class="clock"> <div class="hour"></div&…

    JavaScript 2023年5月27日
    00
  • javascript学习笔记(八)正则表达式

    JavaScript学习笔记(八)正则表达式 什么是正则表达式? 正则表达式是一种高级的文本匹配工具,它允许您通过定制化的模式来识别文本中的特定字符和模式。使用正则表达式可以快速,简单地从大量的文本或数据中提取信息,这是数据分析、数据挖掘等领域中必备的技能。 正则表达式语法 正则表达式是由文本字符和特殊字符构成的文本模式。下面是一些基本的正则表达式语法: ^…

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