观察者模式

2020-10-25  本文已影响0人  乙腾

case

image.png

非设计模式code
SimpleWeatherData

package com.pl.designMode.observer.simple;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName SimpleWeatherData
 * @Author pl
 * @Date 2020/10/25
 * @Version V1.0.0
 */
public class SimpleWeatherData {
    private float temperatrue;
    private float pressure;
    private float humidity;
    //第三方
    private SimpleBaidu simpleBaidu;

    public void setData(float temperatrue, float pressure, float humidity) {
        this.temperatrue = temperatrue;
        this.pressure = pressure;
        this.humidity = humidity;
        dataChange();
    }

    public void dataChange(){
        simpleBaidu.update(getTemperatrue(),getPressure(),getHumidity());
    }

    public float getTemperatrue() {
        return temperatrue;
    }

    public void setTemperatrue(float temperatrue) {
        this.temperatrue = temperatrue;
    }

    public float getPressure() {
        return pressure;
    }

    public void setPressure(float pressure) {
        this.pressure = pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }

    public SimpleBaidu getSimpleBaidu() {
        return simpleBaidu;
    }

    public void setSimpleBaidu(SimpleBaidu simpleBaidu) {
        this.simpleBaidu = simpleBaidu;
    }
}

SimpleBaidu

package com.pl.designMode.observer.simple;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName SimpleBaidu
 * @Author pl
 * @Date 2020/10/25
 * @Version V1.0.0
 */
public class SimpleBaidu {
    // 温度,气压,湿度
    private float temperature;
    private float pressure;
    private float humidity;

    //更新 天气情况,是由 WeatherData 来调用,我使用推送模式
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }

    //显示
    public void display() {
        System.out.println("***Today mTemperature: " + temperature + "***");
        System.out.println("***Today mPressure: " + pressure + "***");
        System.out.println("***Today mHumidity: " + humidity + "***");
    }
}

SimpleClient

package com.pl.designMode.observer.simple;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName SimpleClient
 * @Author pl
 * @Date 2020/10/25
 * @Version V1.0.0
 */
public class SimpleClient {
    public static void main(String[] args) {
        SimpleWeatherData simpleWeatherData = new SimpleWeatherData();
        SimpleBaidu simpleBaidu = new SimpleBaidu();
        simpleWeatherData.setSimpleBaidu(simpleBaidu);
        simpleWeatherData.setData(22,21,11);
    }
}

优缺点

优点:
线性思维,通过每次setData通知第三方
缺点:
违反ocp原则,即对扩展开放,对修改关闭。当新加入第三方时候,SimpleWeatherData需要跟着改,没有扩展性。

Observer code

Observer

package com.pl.designMode.observer.oberserverDesign;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName Observer
 * @Author pl
 * @Date 2020/10/25
 * @Version V1.0.0
 */
public interface Observer {
    void update(float temperature, float pressure, float humidity);
}

Subject

package com.pl.designMode.observer.oberserverDesign;

/**
 * @Auther: pl
 * @Date: 2020/10/25 11:00
 * @Description:
 */
public interface Subject {

    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}


WeatherData

package com.pl.designMode.observer.oberserverDesign;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * @Description: TODO
 * </p>
 * @ClassName WeatherData
 * @Author pl
 * @Date 2020/10/25
 * @Version V1.0.0
 */
public class WeatherData implements Subject {
    private float temperatrue;
    private float pressure;
    private float humidity;
    //第三方
    private List<Observer> observerList;

    /**
     * 空参构造 为成员observerList变量赋值
     *
     * @param
     * @return
     * @exception
     * @author silenter
     * @date 2020/10/25 11:17
    */
    public WeatherData() {
        observerList = new ArrayList<>();
    }


    /**
     * 数据变更
     *
     * @param temperatrue
     * @param pressure
     * @param humidity
     * @return void
     * @exception
     * @author silenter
     * @date 2020/10/25 11:18
    */
    public void setData(float temperatrue, float pressure, float humidity) {
        this.temperatrue = temperatrue;
        this.pressure = pressure;
        this.humidity = humidity;
        notifyObservers();
    }

    /**
     *Observer 注册
     *
     * @param o
     * @return void
     * @exception
     * @author silenter
     * @date 2020/10/25 11:13
    */
    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    /**
     * 移除观察者
     *
     * @param o
     * @return void
     * @exception
     * @author silenter
     * @date 2020/10/25 11:14
    */
    @Override
    public void removeObserver(Observer o) {
        observerList.remove(o);
    }

    /**
     * 通知观察者
     *
     * @param
     * @return void
     * @exception
     * @author silenter
     * @date 2020/10/25 11:14
    */
    @Override
    public void notifyObservers() {
        observerList.forEach((data)->{
            dataChange(data);
        });
    }

    public void dataChange(Observer o){
        o.update(getTemperatrue(),getPressure(),getHumidity());
    }

    public float getTemperatrue() {
        return temperatrue;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

    public List<Observer> getObserverList() {
        return observerList;
    }

}

CurrentConditions

package com.pl.designMode.observer.oberserverDesign;

public class CurrentConditions implements Observer {

    // 温度,气压,湿度
    private float temperature;
    private float pressure;
    private float humidity;

    // 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }

    // 显示
    public void display() {
        System.out.println("***Today mTemperature: " + temperature + "***");
        System.out.println("***Today mPressure: " + pressure + "***");
        System.out.println("***Today mHumidity: " + humidity + "***");
    }
}

BaiduSite

package com.pl.designMode.observer.oberserverDesign;

public class BaiduSite implements Observer {

    // 温度,气压,湿度
    private float temperature;
    private float pressure;
    private float humidity;

    // 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
    @Override
    public void update(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        display();
    }

    // 显示
    public void display() {
        System.out.println("===百度网站====");
        System.out.println("***百度网站 气温 : " + temperature + "***");
        System.out.println("***百度网站 气压: " + pressure + "***");
        System.out.println("***百度网站 湿度: " + humidity + "***");
    }

}

Client

package com.pl.designMode.observer.oberserverDesign;

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建一个WeatherData
        WeatherData weatherData = new WeatherData();

        //创建观察者
        CurrentConditions currentConditions = new CurrentConditions();
        BaiduSite baiduSite = new BaiduSite();

        //注册到weatherData
        weatherData.registerObserver(currentConditions);
        weatherData.registerObserver(baiduSite);

        //测试
        System.out.println("通知各个注册的观察者, 看看信息");
        weatherData.setData(10f, 100f, 30.3f);


        weatherData.removeObserver(currentConditions);
        //测试
        System.out.println();
        System.out.println("通知各个注册的观察者, 看看信息");
        weatherData.setData(10f, 100f, 30.3f);
    }

}

观察者模式介绍

对象之间多对一依赖的一种设计方案,被依赖的对象为 Subject,依赖的对象为 Observer,Subject通知 Observer 变化,比如这里的奶站是 Subject,是 1 的一方。用户时 Observer,是多的一方。

使用场景

适用于通知的场景,一个数据变更,需要通知多个监听者。

代码实现

观察者模式首先通过代码声明了subject,obersever,都是借口,在管理观察者的类中,通过指定obersever类型的接口来管理oberserver集合,这样只要第三方实现了oberserver接口,就可以放到观察者集合中管理,其实核心依旧是面向接口开发,类的多态。

类图

image.png

23种设计模式

设计模式是jdk提供的一些应对不同业务场景的策略。

上一篇 下一篇

猜你喜欢

热点阅读