设计模式之观察者模式

个人理解,如有错误,请大家指出,感谢!

1.什么是观察者模式?

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

比如说,我们要设计一个气象站的显示牌,当气温、湿度等改变了,就更新显示牌。一种做法是,所有显示牌轮询气象数据,当气象数据与上次轮询得到的数据不一致时,就更新显示牌,这是一种很糟糕的做法,浪费了我们的资源(至少浪费了CPU)。

那么观察者模式就可以很好地应用于这个例子,套到定义中是:显示牌作为依赖,当气象数据改变时,就通知显示牌,所有显示牌都会收到通知并自动更新显示。

我可以看到:

1.这种以通知代替轮询的做法大大节省了我们的资源。

2.这种做法实现了解耦,显示牌不再需要直接调用气象数据,而是在气象数据中维护了一组显示牌的引用,当气象数据发生改变时,循环调用显示牌的更新方法。

2.示例

UML图如下:

好了,我们开始写代码:

首先是我们的Subject接口:

public interface Subject {

    void registerObserver(Observer o); //接口中的属性默认都是public的

    void removeObserver(Observer o);

    void notifyObserver();
}

Subject接口的实现类WeatherData:

import java.util.ArrayList;

public class WeatherData implements Subject {

    private ArrayList<Observer> observers;

    private float temp;

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

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObserver() {
        for (Observer observer : observers) {
            observer.update(temp);
        }
    }

    public void measureChanged() {
        notifyObserver();
    }

    public void setTemp(float temp) {
        this.temp = temp;
        measureChanged();
    }
}

我们的Observer接口:

public interface Observer {
    void update(float temp);
}

Display接口(这个接口的目的是:平时自己写代码玩一玩,也要规范一点):

public interface Display {
    void display();
}

显示牌(实现了Observer接口和Display接口):

public class Board implements Observer, Display {

    private float temp;

    //有人可能会问,为什么要有这个引用?
    //我们之后可以看到,有了这个引用,注册和取消注册会比较方便
    private Subject weatherData;

    public Board(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);//注册
    }

    @Override
    public void display() {
        System.out.println("temp: "+temp);
    }

    @Override
    public void update(float temp) {
        this.temp = temp;
        display(); //温度改变,就会显示
    }
}

大功告成!测试代码:

public class WeatherStation {

    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();

        Board board = new Board(weatherData);

        weatherData.setTemp(30);

    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值