Observer-观察者模型

概念:
定义对象间的一种一对多的依赖关系
当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,本质是触发联动

结构:
1 目标对象的定义
2 具体的目标对象定义
3 观察者的接口定义
4 观察者的具体实现

触发时机:
是在完成状态维护后触发,因为通知会传递数据,不能先通知,后改数据,这会导致观察者和目标对象状态不一致
通知观察着的顺序是不一定的,观察者的实现,不能依赖于通知的顺序
多个观察者的顺序是平行的,相互不应该有先后以来的关系

推拉模型:
推模型:
目标对象主动向观察者推送目标的详细信息,推送的信息通畅是目标对象的全部or部分数据,相当于在广播通讯

拉模型:
目标对象在通知观察者的时候,值传递少量信息,如果观察者需要更具体的信息,由观察者主导到目标对象中获取,相当于是观察者从目标对象中拉数据,一版这种模型的实现中,会把目标对象通过update方法,传递给观察者

推模型 是假定目标对象知道观察者需要的数据,会使得观察者难以复用
拉模型是目标对象不知道观察者具体需要什么数据,因此只能把自身传递给观察者,拉模型基本适应各种情况的需要

可以区别对待观察者:
根据不同的状态进行不同的通知

代码实例:

/**
 *  主题
 */
public interface Subject {
    // 观察者注册
    public void registerObserver(Observer o);
    // 删除观察者
    public void removeObserver(Observer o);
    // 当主题有内容更新时调用,用于通知观察者
    public void notifyObserver();
}
/**
 *  用于布告板显示
 */
public interface DisplayElement {
    // 在显示布告板上显示的操作
    public void display();
}
/**
 * 气象站实现主题,发布气象信息(气温)
 */
public class WeatherStation implements Subject{
    private ArrayList observers;
    private float temp;

    public WeatherStation() {
        // 加个ArrayList存放所有注册的Observer对象;
        observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer o) {
        // 当新的观察者注册时添加进来
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        // 当观察者取消注册时去除该观察者
        int i = observers.indexOf(o);
        if (i>=0) {
            observers.remove(i);
        }
    }

    @Override
    public void notifyObserver() {
        // 更新状态,调用Observer的update告诉观察者有新的信息
        for (int i = 0; i < observers.size(); i++) {
            Observer observer = (Observer) observers.get(i);
            observer.update(temp);
        }
    }

    /*
     *  此方法用于气象站收到的数据,并且调用更新使数据实时通知给观察者
     */
    public void setMeasurements(float temp){
        this.temp = temp;
        System.out.println("气象站测量的温度为:" + temp + "℃");
        notifyObserver();
    }
}
/**
 * 布告板上的状态显示
 */
public class ConditionDisplay implements Observer,DisplayElement{
    private float temp;
    private Subject weatherStation;

    public ConditionDisplay(Subject weatherStation) {
        // 构造时需要间主题/被观察者对象作为注册之用
        this.weatherStation = weatherStation;
        weatherStation.registerObserver(this);
    }

    @Override
    public void display() {
        // 将数据显示在布告板上
        System.out.println("布告板显示当前温度为:" + temp + "℃");
    }

    @Override
    public void update(float temp) {
        // 接受来自主题/被观察者(气象站)的数据
        this.temp = temp;
        display();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值