博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之订阅/发布模式(subscribe/publish)
阅读量:5767 次
发布时间:2019-06-18

本文共 3610 字,大约阅读时间需要 12 分钟。

一、什么是订阅发布模式

订阅发布模式定义了一种 一对多 的依赖关系,一指发布者,比如某个主题对象,多指订阅者,依赖是订阅者对发布者的依赖;多个订阅者同时监听一个主题对象。当发布者即主题对象的状态发生变化时,会将该变化通知给订阅者,订阅者据此更新自己的状态。是设计模式中用的比较多的一种。

二、为什么使用订阅发布模式

订阅发布模式旨在降低系统不同模块之间的耦合度。一个复杂的系统一般要划分为好多不同的类,这些对象之间并不独立,存在各种协作关系,这就需要维护对象之间的一致性,这给系统的维护、重用和扩展带来不便,严重限制了系统的灵活性。这样就可以把主动变化因素抽象出来形成发布者,而其他依赖者抽象为订阅者,使他们可以独立的被复用和维护。双发都只依赖与抽象,而不是依赖于具体实现。比如发布者新增一个订阅者时只需要发布者注册一下,订阅者新增依赖时,只需要将自己注册到新的发布者即可。

三、一个例子:

有一个天气预报系统,负责通知明天的天气情况。有几个角色订阅了该系统,他们根据明天的天气情况安排明天的事务。这几个角色分别为农夫、建筑工人、程序员。

下雨天

农夫喜出望外:又可以好好歇一天了,让庄稼庄稼好好成长吧;
建筑工人欣喜万分:完美,睡到天昏地暗;
程序员:继续上班,关我毛事;

日晴万里

农夫感慨:即将迎接充实的一天,收获满满;
建筑工人牢骚:这么大太阳,苦逼的一天;
程序员:继续上班,关我毛事;

使用Java语言具体实现过程:

1.发布者接口:

/*发布者接口,定义注册发布者,删除发布者,发布消息的接口*/public interface IWeather {        void addSubscriber(ISubscriber subscriber);        void delSubscriber(ISubscriber subscriber);        void publishInfo(String msg);    }复制代码

2.发布者具体实现

import org.apache.log4j.Logger;import java.util.ArrayList;import java.util.List;/*发布者具体实现类*/public class WeatherServer implements IWeather {    private static final Logger logger = Logger.getLogger(WeatherServer.class);    /*用来保存注册了的所有订阅者*/    private List
subscribers = new ArrayList
(); public void addSubscriber(ISubscriber subscriber) { subscribers.add(subscriber); logger.info("a new subscriber is joining"); } public void delSubscriber(ISubscriber subscriber) { subscribers.remove(subscriber); logger.info("a subscriber is leaving"); } public void publishInfo(String msg) { for(ISubscriber subscriber : subscribers) subscriber.todoTomorrow(msg); logger.info(String.format("publish a msg: %s ",msg)); }}复制代码

3.订阅者接口

/*订阅者接口,所有订阅WeatherServer 的订阅者都要实现该接口,定义了收到发布者消息之后做出反应的方法*/public interface ISubscriber {    void todoTomorrow(String msg);}复制代码

4.具体订阅者实现

import org.apache.log4j.Logger;public class Farmer implements ISubscriber{    private static final Logger logger = Logger.getLogger(Farmer.class);    public void todoTomorrow(String msg) {        if("rain".equals(msg)){            logger.info("FARMER : a wonderful day!!!");        }else if("sunny".equals(msg)){            logger.info("FARMER : a enrich day!!!");        }else {            logger.info("FARMER : Spam messages");        }    }}public class Worker implements ISubscriber{    private static final Logger logger = Logger.getLogger(Farmer.class);    public void todoTomorrow(String msg) {        if("rain".equals(msg)){            logger.info("WORKER : a satisfied day!!!");        }else if("sunny".equals(msg)){            logger.info("WORKER : a terrible day!!!");        }else {            logger.info("WORKER : Spam messages");        }    }}public class Programmer implements ISubscriber{    private static final Logger logger = Logger.getLogger(Farmer.class);    public void todoTomorrow(String msg) {        if("rain".equals(msg)){            logger.info("PROGRAMMER :raining??? Irrelevant !!!");        }else if("sunny".equals(msg)){            logger.info("PROGRAMMER : sunny Irrelevant !!!");        }else {            logger.info("PROGRAMMER : Spam messages");        }    }}复制代码

5.测试类

*/public class Boot {    public static void main(String[] args){        Farmer farmer = new Farmer();        Worker worker = new Worker();        Programmer programmer = new Programmer();        WeatherServer weatherServer = new WeatherServer();        weatherServer.addSubscriber(farmer);        weatherServer.addSubscriber(worker);        weatherServer.addSubscriber(programmer);        weatherServer.publishInfo("rain");    }}复制代码

6.运行结果:

有一个新的订阅者想要订阅天气预报的服务时,只需要调用weather的注册方法addSubscriber完成注册就能收到天气预报的信息。

转载地址:http://jbbux.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
显式锁(第十三章)
查看>>
看linux书籍做的一些重要笔记(2011.07.03更新)
查看>>
CString、Char* ,char [20]、wchar_t、unsigned short转化
查看>>
从案例学RxAndroid开发(上)
查看>>
Redis学习手册(内存优化)
查看>>
浅尝TensorFlow on Kubernetes
查看>>
springboot系列十 Spring-Data-Redis
查看>>
excel进行矩阵计算
查看>>
基于Android平台的动态生成控件和动态改变控件位置的方法
查看>>
linux 死机分析
查看>>
BOM
查看>>
iOS: Block的循环引用
查看>>
ECC椭圆曲线详解(有具体实例)
查看>>
Linux常见命令(二)
查看>>
PyCharm切换解释器
查看>>
jmp far ptr s所对应的机器码
查看>>
css详解1
查看>>
MySQL类型转换
查看>>
HashSet HashMap 源码阅读笔记
查看>>