首页 > 其他分享 >观察者模式

观察者模式

时间:2023-08-06 16:02:16浏览次数:33  
标签:temperature weatherData void float 观察者 模式 humidity pressure

**介绍:**定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。

**主要解决:**一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

**何时使用:**一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

**如何解决:**使用面向对象技术,可以将这种依赖关系弱化。

**关键代码:**在抽象类里有一个 ArrayList 存放观察者们。

应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

设计原则:

为了交互对象之间的松耦合设计而努力

upload successful

import java.util.ArrayList;

/**
 * 描述:观察者模式 
 * tips:java已有对观察模式的支持,此处是自己实现
 * Created by zhujiawen on 2018-11-03 20:36
 */
public class ObserverTest {
    public static void main(String[] args) throws InterruptedException {
        WeatherData weatherData = new WeatherData();

        CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
        weatherData.setMeasurements(22,33,400);
        Thread.sleep(3000);
        weatherData.setMeasurements(20,35,420);
        Thread.sleep(3000);
        weatherData.setMeasurements(18,37,440);
    }
    //观察者模式-主题
    interface Subject {
        void registerObserver(Observer o );
        void removeObserver(Observer o );
        void notifyObserver();
    }
    //观察者模式-观察者
    interface Observer {
        void update(float temperature, float humidity, float pressure);
    }

    interface DisplayElement {
        void display();
    }

    static class WeatherData implements Subject {

        private ArrayList<Observer> observers;
        private float temperature;//温度
        private float humidity;//湿度
        private float pressure;//压力

        public WeatherData() {
            observers = new ArrayList();

        }

        @Override
        public void registerObserver(Observer o) {
            observers.add(o);
        }

        @Override
        public void removeObserver(Observer o ) {
            int i = observers.indexOf(o);
            if (i >= 0) {
                observers.remove(o);
            }
        }

        @Override
        public void notifyObserver() {
            for (Observer observer : observers) {
                observer.update(temperature, humidity, pressure);
            }
        }

        public void measurementsChanged() {
            notifyObserver();
        }

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

    }

    static class CurrentConditionsDisplay implements Observer, DisplayElement {

        private float temperature;
        private float humidity;
        private float pressure;
        private Subject weatherData;

        public CurrentConditionsDisplay(Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }


        @Override
        public void display() {
            System.out.println(String.format("通知部门已收到数据已变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
        }

        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }

    static class ForecastDisplay implements Observer, DisplayElement {
        private float temperature;
        private float humidity;
        private float pressure;
        private Subject weatherData;

        public ForecastDisplay(Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }


        @Override
        public void display() {
            System.out.println(String.format("预测部门已收到数据已变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
        }

        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }
    
    static class StatisticsDisplay implements Observer, DisplayElement {
        private float temperature;
        private float humidity;
        private float pressure;
        private Subject weatherData;

        public StatisticsDisplay(Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }


        @Override
        public void display() {
            System.out.println(String.format("统计部门已收到数据变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
        }

        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    }
}

标签:temperature,weatherData,void,float,观察者,模式,humidity,pressure
From: https://blog.51cto.com/u_11906056/6984944

相关文章

  • 装饰者模式
    装饰者模式**装饰者模式:**动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。*设计原则:*类应该对扩展开放,对修改关闭继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。组合和......
  • 工厂方法模式
    工厂方法模式**工厂方法模式:**定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。设计原则:依赖倒置原则:要依赖抽象,不要依赖具体类。下面的指导方针,能避免在OO设计原则中违反依赖倒置原则:变量不可以持有具体的类的引用。不要让......
  • 【Java】智慧工地管理系统源码(SaaS模式)
    智慧工地是聚焦工程施工现场,紧紧围绕人、机、料、法、环等关键要素,综合运用物联网、云计算、大数据、移动计算和智能设备等软硬件信息技术,与施工生产过程相融合。一、什么是智慧工地智慧工地是指利用移动互联、物联网、智能算法、地理信息系统、大数据挖掘分析等信息技术,提高项目......
  • openGauss学习笔记-32 openGauss 高级数据管理-批处理模式
    openGauss学习笔记-32openGauss高级数据管理-批处理模式openGauss支持从文本文件执行SQL语句。openGauss提供了gsql工具实现SQL语句的批量处理。以下场景建议使用批处理:如果您重复运行查询(例如,每天或每周),将其设为脚本可以让您避免每次进行重复输入。您可以通过复制和编辑脚......
  • C++工厂模式简易实现
    C++工厂模式简易实现引言:动态绑定是面向对象编程的重要功能,但C++目前还没有纳入标准库的反射机制,所以为了更方便的动态构造对象,使得通过配置文件的方式改变派生类对象,而不需要去修改代码,所以可以使用工厂这一常见的设计模式,来完成类对象的动态构造。基于C++11的新特性和模板,实现......
  • C#中CLR核心机制解析:垃圾回收与标准Dispose模式
    一、CLR核心机制1.1-创建对象的流程分配内存把对象传入到构造函数构造函数使用当前实例返回1.2-什么是堆/栈?堆-Heap:托管堆;一个程序运行时,该进程存放引用类型变量的一块内存,他是全局唯一的。栈-Stack:先进后出数据结构,线程栈;每一个线程存放变量和值类型的内存,随着线程......
  • day 122 - bean的作用域,生命周期,工厂模式
    bean的作用域在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围singleton(默认)在IOC容器中,这个bean的对象始终为单实例在ioc容器初始化时创建对象prototype这个bean在IOC容器中有多个实例在获取bean时创建对象<!--scope设置bean的作用域:......
  • k8s部署DataEase1.16.0cluster模式
    1.下载官方helm  chart包下载地址:https://github.com/mfanoffice/dataease-helm/releases,当前最新为1.16.0#下载并解压helmchart包wgethttps://github.com/mfanoffice/dataease-helm/releases/download/1.16.0/dataease-1.16.0.tgztarxfdataease-1.16.0.tgzcddataease......
  • 转变税务管理模式,实现“四精”
        中共中央办公厅、国务院办公厅前不久印发了《关于进一步深化税收征管改革的意见》(以下简称《意见》),对深入推进“四精”即精确执法、精细服务、精准监管、精诚共治,深化税收征管改革作出了全面部署,为“十四五”时期税收工作确立了总体规划。科技的发展为税收征管现代化提......
  • 迭代器模式-18
    概述迭代器模式(IteratorPattern)又称游标(Cursor)。它提供了一种方式访问聚合对象中的元素而不用暴露这个对象的内部表示。优点:符合“单一职责原则”、“开闭原则”。缺点:增加系统复杂度。interfaceIterator{voidfirst();voidnext();booleanhasNext();O......