设计者模式(二)----观察者模式

介绍 :
  • 主题和观察者是一对多的关系 建立一套触发机制 当主题数据发生改变时 通知观察者数据已更新

  • 缺点 : 1.当观察者多时 通知到所有观察者的时间会变长 2.观察者并不知道主题是如何变化的 仅仅知道主题发送了改变

  • 类图如下

在这里插入图片描述

这里我们以报社为例 报社是主题 订阅报纸的是观察者
  • 我们如果需要报纸 就需要到报社去订阅 此时在代码里 需要一个注册方法把观察者注册进去 当我们订阅一段时间后突然不想看了 就需要告诉报社 以后不要继续给我送报纸了 那么使用代码实现就是一个删除观察者的方法 当报社有新消息时 需要通知观察者 那么还需要一个通知方法 代码实现如下
public interface Subject {

    //注册方法
    void registerObserver(Observer o);
    //取消注册
    void remoteObserver(Observer o);
    //主题改变时通知观察者
    void notifyObserver();
}
========================
public class WeatherData implements Subject {

    private ArrayList<Observer> observerList;//存储所有观察者
    //下面是主题状态  当状态修改时  去通知观察者
    private float temperature;//温度
    private float humidity;//湿度
    private float pressure;//压力

    public WeatherData() {
        this.observerList = new ArrayList<Observer>();
    }

    //注册
    @Override
    public void registerObserver(Observer o) {
        observerList.add(o);
    }

    //取消注册
    @Override
    public void remoteObserver(Observer o) {
        observerList.remove(o);
    }

    //通知
    @Override
    public void notifyObserver() {
        for (Observer o : observerList) {
            o.update(temperature,humidity,pressure);
        }
    }

    //当主题数据变化时 通知观察者
    public void measurementChange(){
        notifyObserver();
    }

    //模拟修改主题数据
    public void setMeasureMent(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementChange();
    }
}
  • 以上是主题实现 接下来我们来看看观察者的实现
  • 观察者只需要被动接收数据集合 订阅报纸不需要每天都去报社去问有没有新消息 而是报社主动去通知你
  • 在这里 我们在通知观察者时是一个方法 而观察者要查看数据时提供一个方法 可以根据自己需要把2个方法合并为一个方法
public interface Observer {
    /**
     * 当数据发送改变时主题会把这些状态值作为方法参数 发送给观察者
     * @param temp
     * @param humidity
     * @param pressure
     */
    void update(float temp,float humidity,float pressure);
}
========
public interface Displayelement {
    void display();
}
========
public class CurrentConditionDisplay implements Observer, Displayelement {

    private float temperature;//温度
    private float humidity;//湿度
    private float pressure;//压力

    //注册自己到主题
    public CurrentConditionDisplay(Subject weatherData) {
        weatherData.registerObserver(this);
    }


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


    @Override
    public void display() {
        System.out.println("CurrentConditionDisplay{" +
                "temperature : " + temperature +
                ", humidit : " + humidity +
                ", pressure : " + pressure +
                '}');
    }
}
  • 测试
public class Test {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();//创建主题
        CurrentConditionDisplay current = new CurrentConditionDisplay(weatherData);//创建观察者并注册到主题

        //修改主题数据
        weatherData.setMeasureMent(1.0f,2.0f,3.3f);
        weatherData.remoteObserver(current);
        weatherData.setMeasureMent(1.0f,2.0f,3.3f);
    }
}
以上为我们自定义实现 在java中也提供了观察者的接口和主题类供我们使用
  • 在这里主题继承Observable类
public class weather extends Observable {
    /**
     * 修改changed属性为true 此时才会通知观察者  否则不会
     */
    @Override
    public void setChanged() {
        super.setChanged();
    }

    /**
     * 修改changed属性为false
     */
    @Override
    public void clearChanged() {
        super.clearChanged();
    }
}
  • 观察者实现Observer接口
public class Current implements Observer {
    /**
    * arg : 通知消息
    */
    @Override
    public void update(Observable o, Object arg) {
        System.out.println(o + "--" + arg);
    }

}
  • 测试
public class Demo {

    public static void main(String[] args) {
        weather weather = new weather();
        Current current = new Current();
        weather.addObserver(current);

        weather.setChanged();
        weather.notifyObservers("11111");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值