发布订阅模式

2023-10-17 08:36:01 浏览数 (2)

概述

发布—订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。

其中包含三个对象:发布者,订阅者,发布中心,接下来就进行代码的编写

代码编写

发布者与订阅者

其中id就是发布者与订阅者的唯一标识

代码语言:javascript复制
//发布者
class Publisher{
    private Integer id;
    public Publisher(Integer id){
        this.id = id;
    }
    public Integer getId(){
        return id;
    }
}

//订阅者
class Subscripter{
    private Integer id;
    public Subscripter(Integer id){
        this.id = id;
    }
    public Integer getId(){
        return id;
    }
}

中心与消息

代码语言:javascript复制
//消息
class Message{
    String content;
    public Message(String content){
        this.content = content;
    }
    public String getContent(){
        return content;
    }
}

//发布订阅中心需要实现的功能
interface PublishAndSubscriptionService{
    //订阅
    public boolean subscribe(Subscripter subscripter,Publisher publisher);
    //取消订阅
    public boolean unsubscribe(Subscripter subscripter,Publisher publisher);
    //发送消息
    public void sendMessage(Publisher publisher,Message message);
}

//具体的发布订阅中心
class PubAndSubCenter implements PublishAndSubscriptionService{
    private Map<Integer, Set<Integer>> map;
    public PubAndSubCenter(){
        map = new HashMap<>();
    }

    @Override
    public boolean subscribe(Subscripter subscripter, Publisher publisher) {
        //发布者id
        Integer publisherId = publisher.getId();
        //订阅者id
        Integer subscripterId = subscripter.getId();
        //这个发布者有那些id
        Set<Integer> subIds = map.getOrDefault(publisherId, new HashSet<Integer>());
        boolean flag = subIds.add(subscripterId);
        if(flag){
            return map.put(publisherId, subIds) != null;
        }
        return false;
    }

    @Override
    public boolean unsubscribe(Subscripter subscripter, Publisher publisher) {
        //发布者id
        Integer publisherId = publisher.getId();
        //订阅者id
        Integer subscripterId = subscripter.getId();
        //这个发布者有那些id
        Set<Integer> subIds = map.getOrDefault(publisherId, new HashSet<Integer>());
        boolean flag = subIds.remove(subscripterId);
        if(flag){
            return map.put(publisherId,subIds) != null;
        }
        return false;
    }

    @Override
    public void sendMessage(Publisher publisher, Message message) {
        Integer publisherId = publisher.getId();
        Set<Integer> subIds = map.getOrDefault(publisherId, new HashSet<Integer>());
        for (Integer subId : subIds) {
            System.out.println("发布者 [" publisherId "] 给订阅者 [" subId "] 发布了消息 [" message.getContent() "]");
        }
    }

代码测试

代码语言:javascript复制
//两个发布者
        Publisher p1 = new Publisher(1);
        Publisher p2 = new Publisher(2);

        //两个订阅者
        Subscripter s1 = new Subscripter(1);
        Subscripter s2 = new Subscripter(2);

        //发布订阅中心
        PubAndSubCenter center = new PubAndSubCenter();

        //s1订阅p1
        center.subscribe(s1,p1);
        //s1订阅p2
        center.subscribe(s1,p2);
        //s2订阅p1
        center.subscribe(s2,p1);

        //发布消息
        center.sendMessage(p1,new Message("p1发送message"));
        center.sendMessage(p2,new Message("p2发送message"));

        System.out.println("=================================");
        //s1取消订阅p1
        center.unsubscribe(s1,p1);
        center.sendMessage(p1,new Message("p1发送message"));
        System.out.println("==================================");

0 人点赞