常用设计模式之——观察者模式、出版订阅模式(订阅广播模式)

本文深入解析观察者模式的原理及应用,通过实例演示如何在项目中实现一对多依赖的自动更新,适用于消息推送、文件共享等场景。

最近项目的需要,刚好用到观察者模式,在这里简单分享下使用心得。观察者模式、出版订阅模式(订阅广播模式)都可以称为观察者模式。

首先看一下观察者模式的定义:

多个对象之间的一对多依赖,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。

典型的应用就是
1、消息推送,比如在oa系统上面,当某个人改变了oa流程的状态,则其他人应该收到修改的消息。
2、还有一种场景就是 文件共享。A用户将文件共享给B用户、C用户、D用户,当A用户对文件进行更新时,就需要对B、C、D用户本地的文件进行同步更新;
3、微信的群聊功能应该也是一种典型的观察者模式;

废话不多说,下面一段代码模拟气象站数据更新时,看板同步更新。
被观察者:气象站(WeatherStation)
观察者:看板(ConditionsDisplay)
更新内容:气象数据(WetherMessage)

首先创建一下接口(观察者和被观察者接口):

package Observe;

/**
 * 观察者,所有观察者都应该实现这个接口
 * */
public interface Observice {
   /**
    * 更新气象数据
    * */
   public void updateMessage(WetherMessage wetherMessage);
}
package Observe;

/**
 * 所有被观察对象都应该继承这个接口
 * */
public interface Subject {
   /**
    * 注册观察者对象
    * */
   public void registerObservice(Observice observice);

   /**
    * 移除观察者对象
    * */
   public void removeObservice(Observice observice);

   /**
    * 提醒所有观察者
    * */
   public void notifyObservice(WetherMessage wetherDate);
}

接下来是具体的对象:
气象观察站:

package Observe;

import java.util.*;

/**
 * 气象台
 * */
public class WeatherStation implements Subject {
   @Override
   public void registerObservice(Observice observice) {
      observices.add(observice);
   }

   @Override
   public void removeObservice(Observice observice) {
      observices.remove(observice);
   }

   @Override
   public void notifyObservice(WetherMessage wetherDate) {
      for(Observice observice : observices) {
         observice.updateMessage(wetherDate);
      }
   }

   private ArrayList<Observice> observices = new ArrayList<>();
}

看板:

package Observe;

/**
 * 气象显示看板
 * */
public class ConditionsDisplay implements Observice {
   public ConditionsDisplay(String name) {
      this.name = name;
   }

   @Override
   public void updateMessage(WetherMessage wetherMessage) {
      this.wetherMessage = wetherMessage;
      System.out.println(name + "数据已经更新,最新数据:" + wetherMessage.toString());
   }

   @Override
   public String toString() {
      return wetherMessage.toString();
   }

   private String name;//看板名称
   private WetherMessage wetherMessage;//气象数据
}

气象数据

package Observe;

public class WetherMessage {
   private float temp;//温度
   private float pressure;//气压

   public float getTemp() {
      return temp;
   }

   public float getPressure() {
      return pressure;
   }

   public WetherMessage(float temp, float pressure) {
      this.temp = temp;
      this.pressure = pressure;
   }

   @Override
   public String toString() {
      return "WetherMessage{" +
            "temp=" + temp +
            ", pressure=" + pressure +
            '}';
   }
}

测试类:

package Observe;

public class Test {
   public static void main(String[] args) {
      WeatherStation weatherStation = new WeatherStation();//创建气象台
      WetherMessage wetherMessage = new WetherMessage(45, 56);//创建气象数据

      ConditionsDisplay conditionsDisplay1 = new ConditionsDisplay("1号展示板");//展示板(监听者)
      ConditionsDisplay conditionsDisplay2 = new ConditionsDisplay("2号展示板");
      ConditionsDisplay conditionsDisplay3 = new ConditionsDisplay("3号展示板");

      weatherStation.registerObservice(conditionsDisplay1);//注册监听者到 气象台中
      weatherStation.registerObservice(conditionsDisplay2);
      weatherStation.registerObservice(conditionsDisplay3);

      weatherStation.notifyObservice(wetherMessage); //气象台更新数据
   }
}

测试结果

1号展示板数据已经更新,最新数据:WetherMessage{temp=45.0, pressure=56.0}
2号展示板数据已经更新,最新数据:WetherMessage{temp=45.0, pressure=56.0}
3号展示板数据已经更新,最新数据:WetherMessage{temp=45.0, pressure=56.0}

Process finished with exit code 0

可以看到,所有注册的观察者都收到消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值