设计模式之观察者模式

观察者模式
1.需求:天气预报项目需求
  • 气象站天天将测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或者第三方)
  • 需要提供开放性API(温度,气压,湿度接口),便于推送
  • 如何设计气象站(一)和多个推送网站(多)之间的关系?
2.观察者模式简单介绍
  • 观察者模式维护了对象之间一对多的关系,被依赖的对象(一)是Subject,依赖的对象是Observer(多)
  • 观察者模式会在Subject中维护了Observer的容器,用来进行观察者的注册,移除和调用观察者本身的方法
  • 观察者模式中的角色
    • Subject: 被依赖的对象,进行登记注册,移除和通知
      • registerObserver() 注册观察者
      • removeObserver() 移除观察者
      • notifyObservers() 通知所有的观察者进行相应的改变(操作容器中的观察者)
3.代码演示

1.uml
在这里插入图片描述

2.代码一览

//观察者接口,由具体观察者实现
public interface Observer {
    //更新信息
    /**
     * 温度
     * 气压
     * 湿度
     * */
    public void update(float temperature,float pressure,float humidity);
}

//具体观察者
public class CurrentConditions implements Observer {
    /**
     * 显示当前天气情况(接入方的网站)
     */
        // 温度,气压,湿度
        private float temperature;
        private float pressure;
        private float humidity;

        //由 WeatherData 来调用,更新至最新的数据(数据从subject中获取)

        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 + "***");
        }
}


//新增的具体观察者
public class LzinnerNet implements Observer {

    /**
     * 显示当前天气情况(接入方的网站)
     */
    // 温度,气压,湿度
    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 mLzinnerTemperature: " + temperature + "***");
        System.out.println("*** Today mLzinnerPressure: " + pressure + "***");
        System.out.println("*** Today mLzinnerHumidity: " + humidity + "***");
    }
}

//被依赖的抽象主体
public interface Subject {
    //注册观察者
    public void registerObserver(Observer o);
    //移除观察者
    public void removeObserver(Observer o);
    //广播信息
    public void notifyObservers();
}

//被依赖的具体主体(内部维护了观察者容器,进行增加,删除和通知)

/**
 * 1. 包含最新的天气情况信息
 * 2. 含有 观察者集合,使用ArrayList进行管理,通知所有的接收者看到最新消息
 * 3. 当数据有更新时,就主动的调用   CurrentConditions对象update方法(含 display), 这样他们(接入方)就看到最新的信息
 */
public class WeatherData implements Subject {
    private float temperature;
    private float pressure;
    private float humidity;
    //观察者集合
    private List<Observer> observers;
    //加入新的第三方

    public WeatherData() {
        observers = new ArrayList<Observer>();
    }

    public float getTemperature() {
        return temperature;
    }

    public float getPressure() {
        return pressure;
    }

    public float getHumidity() {
        return humidity;
    }

//    public void dataChange() {
//        //调用 接入方的 update
//        notifyObservers();
//    }

    //当数据有更新时,就调用 setData =>自动提醒
    public void setData(float temperature, float pressure, float humidity) {
        this.temperature = temperature;
        this.pressure = pressure;
        this.humidity = humidity;
        //调用dataChange, 将最新的信息 推送给 接入方 currentConditions
        notifyObservers();
    }

    //注册一个观察者
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    //移除一个观察者
    @Override
    public void removeObserver(Observer o) {
        if(observers.contains(o)){
            observers.remove(o);
        }
    }

    //遍历所有的Observer 进行更新
    @Override
    public void notifyObservers() {
        for(int i = 0;i < observers.size();i++){
            //Subject给Observer中注入数据 然后调用Observer的展示方法
            observers.get(i).update(this.temperature,this.pressure,this.humidity);
        }
    }
}

//调用者
public class Client {
    public static void main(String[] args) {
        //创建一个WeatherData(具体的subject)
        WeatherData weatherData = new WeatherData();

        //观察者注册入weatherData中
        weatherData.registerObserver(new CurrentConditions());
        //改动一行即可
        //weatherData.registerObserver(new LzinnerNet());
        System.out.println();
        //推送后
        weatherData.setData(30.0f,100,30.3f);
        System.out.println("----------------------------------------------");
        weatherData.setData(30.1f,101,30.4f);

    }
}			

3.运行结果
在这里插入图片描述

注:在观察者模式中,进行观察者的增加和删除十分简单,建立新的具体observer实例,然后在具体subject中增加操作即可(就像上述注释的LzinnerNet一样),其实还是归功于多态的灵活性

参考资料: 韩顺平 java设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值