发布订阅模式代码

 发布订阅模式

所有订阅这个topic的服务都可以得到这个消息。一个消息可被多个订阅者消费。

 

 

package 发布订阅模式;

public interface IPublisher{

    /**
     * 发布者发布消息
     * @param ISubscribePublish  发布到那个公众化:
     * @param message  消息
     * @param isInstantFlag  是否立即可见
     */
    void publish(ISubscribePublish ISubscribePublish, Message message,boolean isInstantFlag);

}



package 发布订阅模式;

public interface ISubscriber {

    /**
     * 订阅公众号
     * @param ISubscribePublish  订阅的公众号
     */
    void subscribe(ISubscribePublish ISubscribePublish);

    /**
     * 取消订阅的公众号
     * @param ISubscribePublish
     */
    void unSubscribe(ISubscribePublish ISubscribePublish);

    /**
     * 接收通知消息
     * @param message
     */
    void notifyMessage(Message message);

}





package 发布订阅模式;


/**
 * 公众号
 */
public interface ISubscribePublish {

    //订阅
    void subscribe(ISubscriber subscriber);

    //取消订阅
    void unSubscribe(ISubscriber subscriber);

    //通知订阅者
    void notifyMessage(ISubscriber subscriber,Message msg);

    //发布通知
    void publish(Message message, boolean isInstantFlag);

}



package 发布订阅模式;


public class Message {

    //消息内容
    private String content;

    public Message(String content){
       this.content = content;
   }

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



package 发布订阅模式;

public interface IQueue<E> {

     int size();

     boolean isEmpty();

     void Push(E element);

     E Pop();

     boolean isFull();
}




package 发布订阅模式;

public class PublisherImpl implements IPublisher{
    @Override
    public void publish(ISubscribePublish subscribePublish, Message message,boolean isInstantFlag) {
        subscribePublish.publish(message,isInstantFlag);
    }
}


package 发布订阅模式;

public class SubscriberImpl implements ISubscriber{


    private String name;

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

    @Override
    public void subscribe(ISubscribePublish subscribePublish) {
        subscribePublish.subscribe(this);
    }

    @Override
    public void unSubscribe(ISubscribePublish subscribePublish) {
        subscribePublish.unSubscribe(this);
    }

    @Override
    public void notifyMessage(Message message) {
        System.out.println(name+"接收到了消息:"+message);
    }
}




package 发布订阅模式;

import java.util.ArrayList;
import java.util.List;

public class SubscribePublishImpl implements ISubscribePublish {

    private String topic;

    private List<ISubscriber> subscriberList = new ArrayList<>();

    private IQueue<Message> queue = new MyQueueImpl(4);

    public SubscribePublishImpl(String topic){
        this.topic = topic;
    }

    @Override
    public void subscribe(ISubscriber subscriber) {
        subscriberList.add(subscriber);
    }

    @Override
    public void unSubscribe(ISubscriber subscriber) {
        subscriberList.remove(subscriber);
    }

    @Override
    public void notifyMessage(ISubscriber subscriber,Message msg) {
        subscriber.notifyMessage(msg);
    }

    @Override
    public void publish(Message message,boolean isInstantFlag) {
        if(isInstantFlag){
            for (ISubscriber subscriber : subscriberList) {
                notifyMessage(subscriber,message);
            }
            return;
        }

        if(queue.isFull()){
            while (!queue.isEmpty()){
                Message message1 = queue.Pop();
                for (ISubscriber subscriber : subscriberList) {
                    notifyMessage(subscriber,message1);
                }
            }
        }

        queue.Push(message);
    }
}



package 发布订阅模式;

import java.util.ArrayList;
import java.util.List;

/**
 * 循环队列:
 *      front指向对头元素
 *      real执行队尾元素的下一个
 * @param <E>
 */
public class MyQueueImpl<E> implements IQueue<E> {

    private E[] array;
    private final int initialCapacity;
    private int front;
    private int real;

    public MyQueueImpl(int initialCapacity){
        this.initialCapacity = initialCapacity;
        array = (E[]) new Object[initialCapacity];
        front = 0;
        real = 0;
    }


    @Override
    public int size() {
        return (real-front+initialCapacity)%initialCapacity;
    }

    @Override
    public boolean isEmpty() {
        return front == real;
    }

    @Override
    public void Push(E element) {
        if(isFull()){
            throw new RuntimeException("队列已满,无法添加元素");
        }
        array[real] = element;
        real = (real+1)%initialCapacity;
    }

    @Override
    public E Pop() {
        if(isEmpty()){
            throw new RuntimeException("队列已空,无法添加元素");
        }

        E element = array[front];
        front = (front+1)%initialCapacity;
        return element;
    }

    @Override
    public boolean isFull() {
        return size() == (initialCapacity-1);
    }
}




package 发布订阅模式;

public class SubPubTest {
    public static void main(String[] args) {
        ISubscribePublish subscribePublish = new SubscribePublishImpl("AgoodBoy");
        IPublisher publisher = new PublisherImpl();
        ISubscriber subscriber1 = new SubscriberImpl("订阅者1");
        ISubscriber subscriber2 = new SubscriberImpl("订阅者2");
        ISubscriber subscriber3 = new SubscriberImpl("订阅者3");

        subscriber1.subscribe(subscribePublish);
        subscriber2.subscribe(subscribePublish);
        subscriber3.subscribe(subscribePublish);

        publisher.publish(subscribePublish,new Message("welcome"),false);
        publisher.publish(subscribePublish,new Message("to"),false);
        publisher.publish(subscribePublish,new Message("here"),true);
        publisher.publish(subscribePublish,new Message("111"),false);
        publisher.publish(subscribePublish,new Message("222"),false);
        publisher.publish(subscribePublish,new Message("333"),false);
        publisher.publish(subscribePublish,new Message("444"),false);
        publisher.publish(subscribePublish,new Message("555"),false);
    }
}


运行结果

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值