【设计模式六之订阅者模式】其实你一直是一个订阅者subscriber

subscriber and publisher

  • 细说发布者与订阅者模式
    • 生活中的发布,订阅
    • 你该了解下这个模型
    • 示例代码
    • 个人觉得和观察者模式的差异区别

细说发布者与订阅者模式

提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041

成年人的世界没有容易二字,从年初一直以来,不是在加班就是在加班的路上,有时候想更新博客的时候,太疲惫了,后来就又渐渐的消了,搞搞自己之前养成的一些习惯,现在也都不复存在,现在趁有点时间,先来一波,找找感觉先,怕真拿不起来了。囧!!!

生活中的发布,订阅

首先来说说发布者和订阅者场景吧,生活中有哪些场景是类似发布者和订阅者关系的。
场景一:
记得上初中的时候,家里面给我订的那种英语报刊,这个报刊上有很多专辑作者,报刊每一月更新一次的时候,送报纸的小哥哥就会把英语报刊送到学习,那在这种场景下,是不是其实就建立了,报刊作者-----报刊专栏-----我三者之间的关系,从里面可以看出来,其实我是作为那个subscriber,作者是publisher,而中间有个专栏,这个专栏其实作为中介,姑且叫做ScriberPublish,这其实就是典型的订阅者和发布者之间的模型,订阅者可以是多个,而发布者也可以是多个,专栏的存在作为中间产物

场景二:
举一个应用里面的东西吧,有玩过喜马拉雅app的,都知道用户是可以去订阅节目的,订阅这个节目后,这个节目的所有者在某个时间点更新节目,平台收到更新会把这种信息推送给所有的订阅用户,在这个模型下节目作者-----节目-----我三者之间的关系也是典型的订阅发布模型。

你该了解下这个模型

【设计模式六之订阅者模式】其实你一直是一个订阅者subscriber_第1张图片
画的不好,见谅撒
从这张图中可以看出来,订阅发布模型下,存在这样的三种角色,发布者publisher,订阅者subscriber,还有一个专栏节目subcribePublish
三者之间也存在一些主次关系,首先订阅者需要订阅专栏,发布者也要与专栏建立某种联系,然后发布者发布某些内容的时候,会去通知已经订阅的所有订阅者。
其实整个原理是很简单的,主要是需要和观察者模式稍微区别一下。

示例代码

先定义一个顶层的发布者接口

package com.zzf.designpattern.subcribe.subcriber;

public interface IPublisher {
    public void publish(SubcribePublish subcribePublish,M message,boolean isInstantMsgs);
}

顶层的订阅者模型,主要用于订阅,取消订阅,以及更新过程

package com.zzf.designpattern.subcribe.subcriber;

public interface ISubcriber {
    public void subcribe(SubcribePublish subcribePublish);

    public void unSubcribe(SubcribePublish subcribePublish);

    public void update(String publisher,M message);
}

消息模型,记录消息来源

package com.zzf.designpattern.subcribe.subcriber;

public class Msg {
    private String publisher;
    private M m;

    public Msg(String publisher,M m){
        this.publisher = publisher;
        this.m = m;
    }

    public String getPublisher(){
        return publisher;
    }

    public void setPublisher(String publisher){
        this.publisher = publisher;
    }

    public M getMsg(){
        return m;
    }
    public void setMsg(M m){
        this.m = m;
    }
}

专栏部分,通过这个专栏将发布者和订阅者结合在一起

package com.zzf.designpattern.subcribe.subcriber;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


public class SubcribePublish {
    private String name;
    final int QUEUE_CAPACITY = 20;

    private BlockingQueue queue = new ArrayBlockingQueue(QUEUE_CAPACITY);
    private List subcribers = new ArrayList();

    public SubcribePublish(String name){
        this.name = name;
    }

    public void publish(String publisher,M message,boolean isInstantMsg){
        if (isInstantMsg){
            update(publisher,message);
            return;
        }
        Msg mMsg = new Msg(publisher,message);
        if (!queue.offer(mMsg)){
            update();
        }
    }

    public void subcribe(ISubcriber subcriber){
        subcribers.add(subcriber);
    }

    public void unSubcribe(ISubcriber subcriber){
        subcribers.remove(subcriber);
    }



    public void update(){
        Msg m = null;
        while ((m = queue.poll())!= null){
            this.update(m.getPublisher(), (M) m.getMsg());
        }
    }


    private void update(String publisher,M msg){
        for (ISubcriber subcriber:subcribers){
            subcriber.update(publisher,msg);
        }
    }
}

具体的订阅者

package com.zzf.designpattern.subcribe.demo;

import com.zzf.designpattern.subcribe.subcriber.ISubcriber;
import com.zzf.designpattern.subcribe.subcriber.SubcribePublish;



public class SubcribeImpl implements ISubcriber {

    private String name;
    public SubcribeImpl(String name){
        this.name = name;
    }
    public void subcribe(SubcribePublish subcribePublish) {
        subcribePublish.subcribe(this);
    }

    public void unSubcribe(SubcribePublish subcribePublish) {
        subcribePublish.unSubcribe(this);
    }

    public void update(String publisher, Object message) {
        System.out.println(this.name +" \t收到 \t"+publisher+" \t发来的消息:"+message.toString());
    }


}

具体的发布者

package com.zzf.designpattern.subcribe.demo;

import com.zzf.designpattern.subcribe.subcriber.IPublisher;
import com.zzf.designpattern.subcribe.subcriber.SubcribePublish;



public class PublishImpl implements IPublisher {
    private String name;
    public PublishImpl(String name){
        super();
        this.name = name;
    }
    
    public void publish(SubcribePublish subcribePublish, M message, boolean isInstantMsgs) {
        subcribePublish.publish(this.name,message,isInstantMsgs);
    }
}

测试部分的代码

package com.zzf.designpattern.subcribe.demo;

import com.zzf.designpattern.subcribe.subcriber.IPublisher;
import com.zzf.designpattern.subcribe.subcriber.ISubcriber;
import com.zzf.designpattern.subcribe.subcriber.SubcribePublish;



public class Test {
    public static final void main(String[] args){
        SubcribePublish subcribePublish  = new SubcribePublish("订阅器");
        IPublisher publisher1 = new PublishImpl("发布者1");
        IPublisher publisher2 = new PublishImpl("发布者1");

        ISubcriber subcriber1 = (ISubcriber) new SubcribeImpl("订阅者1");
        ISubcriber subcriber2 = (ISubcriber) new SubcribeImpl("订阅者2");


        subcriber1.subcribe(subcribePublish);
        subcriber2.subcribe(subcribePublish);

        publisher1.publish(subcribePublish,"作者1发布文章啦",true);
        publisher1.publish(subcribePublish, "作者1又发布文章啦",true);
        publisher1.publish(subcribePublish, "作者1又又又发布文章了",false);


        publisher2.publish(subcribePublish,"作者2在专栏上发布文章了",true);
        publisher2.publish(subcribePublish, "作者2也在发布文章了",false);
        System.out.println("-------------------");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        subcribePublish.update();
    }
}

 
  

有兴趣的看官可以run一下,
看起来这个模型很简单,但是要将整个模型抽象出来,在项目中实际运用到,个人觉得还是有一定难度在里面的,首先是专栏的抽象,其实是发布者的抽象,要专栏和发布者的对应其实是随机混合打乱的关系。可以做到很多种排序

个人觉得和观察者模式的差异区别

一:
观察者模式Observer和Observable之间的行为响应是直接操作的,即被观察者首先去注册所有的观察者对象,当被观察者一旦发生变化是,此时是直接通知所有的观察者,将变化通知给观察者,这种我个人理解为被动响应式观察,被观察者需要去注册所有的观察者对象,由被观察者去通知
而订阅者模型下,订阅者主动去订阅专栏,这种订阅行为是由订阅者主动发起的,发布者与专栏之间建立某种关系后,发布者发布后,触发专栏去通知订阅者,避免了发布者与订阅者之间的直接接触,这种行为是主动行为。

二:
观察者模式是一个被观察者,对应着所有的观察者对象,是单纯的一对多的关系
而订阅者模式由于有了专栏,则可以塑造成多对多,一对多,等等,整个结构下,订阅者可以是多个,专栏也可以是多个,发布者可以是多个,从而打造出一种复杂的消息系统。


在最后谢谢 大家的观看,写的不好的,或者错误的,请各位看官不腻赐教,不懂的地方,也可以相互交流,这也是在记录自己的成长过程的一种方式,谢谢,欢迎持续访问博客:会有更多精彩的

欢迎继续访问,我的博客

你可能感兴趣的:(Java设计模式学习,java设计模式)