设计模式-观察者模式

观察者模式

什么是观察者模式

  1. 出版者(Subject)+订阅者(Observer)=观察者模式
    1. Subject管理某些数据,当数据发生改变,新的数据就会以某种形式送到Observer手上
    2. Observer在订阅(register)主题以便在主题改变时收到更新
  2. 观察者模式定义对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都收到通知并自动更新
  3. 松耦合 任何情况下我们可以添加/删除观察者,主题不会受到任何影响,改变主题或观察者其中一方,并不会影响另一方。只要接口仍被遵守,就可以自由改变他们

代码分析

public interface ISubject {
    /*主题要为它的订阅者提供信息更新服务*/
    void measureChange();
    /*注册/订阅,observer可以订阅这个主题,可以得到这个主题的数据*/
    void addObserver(IObserve io);
    /*退订,observer可以取消订阅这个主题,不会再收到主题的数据*/
    void deleteObserver(int i);
}
public interface IObserve {
    /*主题可以调用订阅者接口的update方法使数据更新*/
    void update(double t,double h,double p);
}
import java.util.ArrayList;

public class WeatherData implements ISubject {
    /*主题仅仅知道有一个订阅者的名单*/
    private ArrayList<IObserve> iObserveArrayList;
    /*数据*/
    private double t;
    private double h;
    private double p;
    WeatherData(){
        iObserveArrayList = new ArrayList<>();
    }
    /*数据更新,主题把所有数据都提供给订阅者供它选择*/
    @Override
    public void measureChange() {
        for(IObserve i:iObserveArrayList){
            i.update(t,h,p);
        }
    }
	/*添加订阅者*/
    @Override
    public void addObserver(IObserve io) {
        iObserveArrayList.add(io);
    }
	/*删除订阅者*/
    @Override
    public void deleteObserver(int i) {
        iObserveArrayList.remove(i);
    }
	/*模拟数据更新的测试方法*/
    public void setT(double t) {
        this.t = t;
    }

    public void setH(double h) {
        this.h = h;
    }

    public void setP(double p) {
        this.p = p;
    }
}
public class Display01 implements IObserve {
    private double t;
    private double h;
    private double p;
    /*类构造出来同时注册成为订阅者*/
    Display01(ISubject is){
        is.addObserver(this);
    }
    /*接收所有的更新数据*/
    @Override
    public void update(double t, double h, double p) {
        this.t = t;
        this.h = h;
        this.p = p;
    }
    public void print(){
        System.out.println("["+t+"]"+"["+h+"]"+"["+p+"]");
    }
}
public class Main {
	//push
    public static void main(String[] args) {
	   WeatherData is = new WeatherData();
	   Display01 d = new Display01(is);
	   is.setH(10.1);
	   is.setP(30.5);
	   is.setT(75);
	   is.measureChange();
	   d.print();
    }
}
  • 主题将所有的信息"push"给了订阅者,订阅者选择信息进行处理
  • 当然另一种方式可以"pull",订阅者向主题请求需要的信息

Java中也有实现的观察者模式的api,可惜采用的是继承的模式,在java9中已弃用

import java.util.Observable;
/*主题类,采用继承,类库Observable*/
public class WeatherData extends Observable {
    /*数据*/
    private double t;
    private double h;
    private double p;
    WeatherData(){ }
	/*数据更新*/
    public void measureChange() {
        /*setChanged()将Observable中的标志置为true*/
        /*在notifyObservers()中将被检测标志,为true就会更新*/
        /*所以在进行更新的时候必须调用setChanged()方法*/
        setChanged();
        notifyObservers();
    }
	/*模拟更新*/
    public void setT(double t) {
        this.t = t;
    }

    public void setH(double h) {
        this.h = h;
    }

    public void setP(double p) {
        this.p = p;
    }

    public double getT() {
        return t;
    }

    public double getH() {
        return h;
    }

    public double getP() {
        return p;
    }
}
import java.util.Observable;
import java.util.Observer;
/*订阅者*/
public class Display02 implements Observer {
    /*主题对象,提供注册*/
    private Observable o;
    private double t;
    private double h;
    private double p;
	/*构造并注册*/
    public Display02(Observable o) {
        this.o = o;
        o.addObserver(this);
    }
	/*更新*/
    /*这里其实不知道算不算"pull",由订阅者选择信息*/
    @Override
    public void update(Observable o, Object arg) {
        if(o instanceof WeatherData) {
            WeatherData w = (WeatherData) o;
            this.h = w.getH();
            this.p = w.getP();
            this.t = w.getT();
        }
    }
    public void print(){
        System.out.println("["+t+"]"+"["+h+"]"+"["+p+"]");
    }
}
public class Main {
    public static void main(String[] args) {
        //pull
        WeatherData w = new WeatherData();
        Display02 d = new Display02(w);
        w.setH(12.4);
        w.setP(45.1);
        w.setT(4);
        w.measureChange();
        d.print();
    }
}
  • 上述使用java.util.Observable,java.util.Observer的某些方法,其他方法查询api
  • 上述写了我理解中的"pull",可能有偏差

以上

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值