设计模式2(观察者模式)

设计模式原则

  1. 不变的和变化的分开。
  2. 针对接口编程,而不针对实现编程。
  3. 多考虑组合,而不是继承。
  4. 为了交互对象之间的松耦合设计而努力。

观察者模式

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

例:

  1. 我们有一个主题,主题里有我们要推送的内容。
  2. 我们有两个观察者,我们一个观察者要计算均值,并展示,一个观察者要输出数据的变化。
  3. 观察者想要获取主题推送的消息我们要先订阅主题的推送功能。
    PS: 主题一对多中的一方,负责在数据变化的时候推送至观察者。观察者接受消息的一方。

设计思想

  1. 考虑第一条设计原则,那么我们要考虑,如何来划分接口内容。PS 这里我们会变化的只有数据,不变的有 1 添加订阅 2 删除订阅 3 推送消息
  2. 考虑第二条设计原,针对接口编程而不针对实现编程,那么我们需要一个接口提供1中的3个方法,这个是针对主题的,而对于所有的观察者我们都需要一个接口来接受主题推送的数据。

总结: 根据上述所说我们现在共有:

  1. 主题类
  2. 主题接口
  3. 2个观察者类
  4. 1个更新接口

类设计如下

主题接口

public interface Subject {

    void addObserver(Observer observer);

    void deleteObserver(Observer observer);

    void notifyObserver(WeatherData.Obj obj);
}

主题类

public class WeatherData implements Subject{

    private List<Observer> list;
	
	// list 订阅列表
    public WeatherData(){
        list = new ArrayList<Observer>();
    }

    @Override
    public void addObserver(Observer observer) {
        list.add(observer);
    }

    @Override
    public void deleteObserver(Observer observer) {
        int i = list.indexOf(observer);
        if(i>=0){
            list.remove(i);
        }
    }

    @Override
    public void notifyObserver(Obj obj) {
        for (Observer observer : list) {
            observer.update(obj);
        }
    }

    public void measurementsChanged(Obj obj){
        notifyObserver(obj);
    }

	// 用于更新数据变化
    static class Obj{

        private int i;
        private int j;

        public int getI() {
            return i;
        }

        public int getJ() {
            return j;
        }

        public void setI(int i) {
            this.i = i;
        }

        public void setJ(int j) {
            this.j = j;
        }
    }

}

观察者接口

public interface Observer {

    public void update(Object obj);

}

统计类

public class StatisticsData implements Observer{

    private WeatherData.Obj ob ;

    private List<WeatherData.Obj> is ;

    public StatisticsData(){
        is = new ArrayList<WeatherData.Obj>();
    }

    @Override
    public void update(Object obj) {
        ob = (WeatherData.Obj) obj;
        is.add(ob);
        iii();
    }

    public void iii(){
        int sumi = 0;
        int sumj = 0;
        for (WeatherData.Obj ob : is){
            sumi +=ob.getI();
            sumj +=ob.getJ();
        }
        System.out.println(String.format("sumi = %s , sumj = %s ,avgi = %s , avgj = %s",sumi,sumj,sumi/is.size(),sumj/is.size()));
    }

}

数据类

public class Data  implements Observer{

    @Override
    public void update(Object obj) {
        WeatherData.Obj ob = (WeatherData.Obj) obj;
        System.out.println(ob.getI() + "   " + ob.getJ());
    }
}

测试类

public class Test {
    static StatisticsData statisticsData = new StatisticsData();
    static Data data = new Data();
 static   WeatherData weatherData = new WeatherData(); 
    public Test(){

    }

    public static void main(String[] args) {

      
        weatherData.addObserver(statisticsData); // 向订阅者内增加 订阅者
        weatherData.addObserver(data);
        for (int i = 0 ; i<5 ; i ++){
            WeatherData.Obj obj = new  WeatherData.Obj();
            obj.setI(i);
            obj.setJ(i+1);
            weatherData.measurementsChanged(obj);
            weatherData.deleteObserver(data);
        }


    }
}

测试结果
在这里插入图片描述
PS: 使用接口是为了解耦合,便于变化。
PS: jvm 中提供了 观察者模式接口,可以 观察者拉取数据变化也支持推送
java.util.Observer(观察者接口);
java.util.Observable(主题类);
有兴趣的可以了解一下
提示 jvm的观察者类中提供了
在这里插入图片描述
这个方法,当数据变化的时候不主动调用 setChanged 方法 消息将不会推送,其他与上述基本一致。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值