zoukankan      html  css  js  c++  java
  • 观察者模式(Observer Pattern)


    是什么?

    怎么用?

    什么情况下用?

    实例!


    观察者模式:

      一个目标对象管理所有依赖于它的观察者对象,并且当它本身的状态改变时主动发出通知。

      这时候就有问题了,目标怎么知道谁是观察者?谁不是观察者?而且目标要怎么通知观察者?

      (个人感觉两个类通信就能用到这东西)

    使用场景:

      今日头条文章发布后需要一系列的后续处理流程,比如更新这个作者创建的文章总数、将这篇文章推荐到对应的频道、划分文章的栏目、上报到推荐系统等等。那要其他的这些要怎么知道文章是否发布呢?这时候就可以用到观察者模式了(事件机制)!

    原理:

      目标类需要:

        1、注册观察者(观察者通知目标:我要当你的观察者)

        2、移除观察者(观察者通知目标:我要溜了)

        3、调用观察者的提供的方法通知观察者

      观察者需要:

        1、提供目标通知观察者时用到的方法

        2、在构造函数中调用目标的注册方法将自己注册成目标的观察者

    例子:

      气象检测例子:

        如图,气象站是获取实际气象数据的物理设备,WeatherData对象是用来追踪气象站的数据,并更新布告板。

        扩充WeatherData对象,使得布告板能够及时更新,并利于以后的扩展。

        

      Subject 是抽象目标,所有的目标都继承这个抽象类,这个抽象类提供了三个最基本的注册、移除、通知观察者的方法!

      WeatherData 是具体目标,继承自抽象目标Subject,这个类的notifyObserver通过调用观察者的udpate方法通知观察者状态变化!

      Observer 是抽象观察者,所有的观察者都继承这个抽象类,这个抽象类提供了udpate方法,以便目标调用。

      CurrentConditionDisplay、StatisticsDisplay 是具体观察者,在这两个类的构造方法中实现了「注册为目标的观察者」!

    <Head First 设计模式> code:

    package Observer;
    
    public interface Subject {
    
        public void registerObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyObserver();
    
    }
    Subject
    package Observer;
    
    import java.util.ArrayList;
    
    public class WeatherData implements Subject{
    
        private ArrayList observers;
        private float temperature;
        private float humidity;
        private float pressure;
    
        public WeatherData() {
            observers = new ArrayList();
        }
    
        public void registerObserver(Observer o) {
            observers.add(o);
        }
    
        public void removeObserver(Observer o) {
            int i = observers.indexOf(o);
            if (i >= 0) {
                observers.remove(i);
            }
        }
    
        public void notifyObserver() {
            for (int i =0; i< observers.size(); i++) {
                Observer observer = (Observer)observers.get(i);
                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();
        }
    }
    WeatherData
    package Observer;
    
    public interface Observer {
    
        public void update(float temp, float humidity, float pressure);
    }
    Observer
    package Observer;
    
    public class CurrentConditionsDisplay implements Observer {
    
        private float temperature;
        private float humidity;
        private float pressure;
        private Subject weatherDay;
    
        public CurrentConditionsDisplay(Subject subject) {
            this.weatherDay = subject;
            weatherDay.registerObserver(this);
        }
    
        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("temp = " + temperature + " humi = " + humidity + " press = " + pressure);
        }
    }
    CurrentConditionsDisplay
    package com.company;
    
    import Observer.CurrentConditionsDisplay;
    import Observer.WeatherData;
    
    public class Main {
    
        public static void main(String[] args) {
    
            WeatherData weatherData = new WeatherData();
    
            CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
    
            weatherData.setMeasurements(1, 3, 4);
        }
    }
    Main

    结果:

    temp = 1.0 humi = 3.0 press = 4.0
  • 相关阅读:
    线程的start和run方法的区别
    GC相关的面试题
    AVR单片机教程——EasyElectronics Library v1.3手册
    我回来了
    继续停更通知
    停更通知
    玩玩24点(上)
    AVR单片机教程——EasyElectronics Library v1.2手册
    AVR单片机教程——数码管
    算法基础课程总结
  • 原文地址:https://www.cnblogs.com/Mr-Wenyan/p/10204004.html
Copyright © 2011-2022 走看看