0
点赞
收藏
分享

微信扫一扫

设计模式(行为型设计模式——观察者模式)

非衣所思 03-26 08:00 阅读 3

设计模式(行为型设计模式——观察者模式)

观察者模式

基本定义

模式结构

代码实现

Subject 抽象主题
/**
 * @Description 抽象主题类
 **/
public interface Subject {

    //注册观察者
    void registerObserve(Observe observe);

    //移除观察者
    void removeObserve(Observe observe);

    //通知观察者
    void notifyAllObserve();
}
ConcreteSubject 具体主题
/**
 * @Description 具体主题
 **/
@Slf4j
public class WeatherSubject implements Subject {

    List<Observe> observes = new ArrayList<>();

    Weather weather;

    /**
     * 实现特定顺序通知观察者,可以自我实现排序方式
     * 如果使用队列保存观者,需提前排序
     * @param observe
     */
    @Override
    public void registerObserve(Observe observe) {
        observes.add(observe);
    }

    @Override
    public void removeObserve(Observe observe) {
        log.info("移除观察者 {}", observe.name());
        observes.remove(observe);
    }


    /**
     * 方式一、直接将更新内容发送给观察者
     * 推模式:通知你发生变化的同时,通过一个参数将变化的细节传递到观察者角色中去。
     *
     * 方式二、通知消息给观察者拉去更新数据
     * 拉模式:目标角色在发生变化后,仅仅告诉观察者角色“我变化了”;观察者角色如果想要知道具体的变化细节,则就要自己从目标角色的接口中得到。
     *
     */
    @Override
    public void notifyAllObserve() {
        if(observes.isEmpty()){
            log.info("暂无观察者");
            return;
        }
        observes.stream().forEach((observe)->{
            observe.update(weather);
        });
    }

    /**
     * 天气更新,通知观察者。
     * 与监听者模式差别在于 事件处理(事件源 + 事件 + 事件监听)
     * @param weather
     */
    public void setWeather(Weather weather) {
        this.weather = weather;
        notifyAllObserve();

        //监听模式,事件处理。可以使用外观模式封装事件处理
        //eventHandle.notifyAllObserve(observes)
    }
}
POJO 普通Java实体:通知内容封装
@Data
public class Weather {

    private String date;
    private int temperature;
    private int humidity;
    private int windPower;

    public Weather(String date, int temperature, int humidity, int windPower) {
        this.date = date;
        this.temperature = temperature;
        this.humidity = humidity;
        this.windPower = windPower;
    }
}
Observer 观察者
/**
 * @Description 抽象观察者
 **/
public interface Observe {

    String name();

    /**
     * @param weather 天气
     */
    void update(Weather weather);
}
ConcreteObserver 具体观察者
/**
 * @Description 具体观察者(APP客户端)
 **/
@Slf4j
public class AppClientObserve implements Observe {

    private Subject weatherSubject;

    //注册观察者, 关联主题
    public AppClientObserve(Subject weatherSubject) {
        this.weatherSubject = weatherSubject;
        this.weatherSubject.registerObserve(this);
    }


    @Override
    public String name() {
        return "App客户端";
    }

    @Override
    public void update(Weather weather) {
        log.info("APP客户端:{} 最新天气:温度 {} ℃, 相对湿度 {} %, 风力 {} 级",
                weather.getDate(), weather.getTemperature(), weather.getHumidity(), weather.getWindPower());
    }
}
/**
 * @Description 具体观察者(H5客户端)
 **/
@Slf4j
public class H5ClientObserve implements Observe {

    private Subject weatherSubject;

    //注册观察者, 关联主题
    public H5ClientObserve(Subject weatherSubject) {
        this.weatherSubject = weatherSubject;
        this.weatherSubject.registerObserve(this);
    }


    @Override
    public String name() {
        return "H5客户端";
    }

    @Override
    public void update(Weather weather) {
        log.info("H5客户端:{} 最新天气:温度 {} ℃, 相对湿度 {} %, 风力 {} 级",
                weather.getDate(), weather.getTemperature(), weather.getHumidity(), weather.getWindPower());
    }
}
Client 客户端:测试类
/**
 * @Description 观察者测试类
 **/
public class Test {
    public static void main(String[] args) {
        WeatherSubject weatherSubject = new WeatherSubject();
        Observe h5Observe = new H5ClientObserve(weatherSubject);
        Observe appObserve = new AppClientObserve(weatherSubject);

        weatherSubject.setWeather(new Weather("2020-4-16 12:00",24, 50, 2));
        weatherSubject.setWeather(new Weather("2020-4-16 16:00",20, 70, 3));

        weatherSubject.removeObserve(h5Observe);
        weatherSubject.setWeather(new Weather("2020-4-16 18:00",15, 65, 1));
    }
}
输出结果

优点

缺点

使用场景

总结

举报

相关推荐

0 条评论