订阅发布功能Java实现

前言

订阅发布最常见的就是在公众号的订阅,用户订阅了公众号后,公众号发布消息时就能收到。其实他相当于设计模式中的观察者模式

大致流程图

订阅发布功能Java实现_第1张图片

用户首先对感兴趣的服务进行订阅,该服务在发送消息时会将消息发送至所有订阅的用户。

实现

接口定义

使用java实现的版本
首先定义下接口,再对其进行实现。

public interface Service {

    boolean addSubscribe(Observice observice); // 增加订阅者

    boolean removeSubscribe(Observice observice); // 删除订阅者

    void push(Object o); // 推送消息
}

这是一个服务的接口,声明了3个主要的方法,分别是增加订阅,删除订阅,以及推送消息。


public interface Observice {

    void gotIt(Object s); // 收到消息后的动作

    String getId();

    String getName();
}

这个接口用来作为用户的接口,提供获取Id,name以及消息订阅后的动作。

接口实现

下面是消息服务的实现,在收到订阅后根据id放到map里,然后根据id删除。

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MessageService implements Service {
    private static Map<String,Observice> observerMap = new ConcurrentHashMap<>();

    @Override
    public boolean addSubscribe(final Observice observice) {
        observerMap.put(observice.getId(),observice);
        System.out.println(String.format("用户Id %s 姓名 %s 插入成功 ", observice.getId(), observice.getName()));
        return true;
    }

    @Override
    public boolean removeSubscribe(final Observice observice) {
        if (observerMap.get(observice.getId()) == null){
            System.out.println(String.format("用户Id %s 姓名 %s 不存在 移除失败", observice.getId(), observice.getName()));
            return false;
        }
        observerMap.remove(observice.getId());
        System.out.println(String.format("用户Id %s 姓名 %s 已经移除 ", observice.getId(), observice.getName()));
        return true;
    }

    @Override
    public synchronized void push(Object S) {
        if (null == S) return;
        observerMap.forEach((k,v)-> v.gotIt(S));// 推送时采用轮训推送
        System.out.println("所有消息推送完毕");
    }

下面是用户接口的实现,在收到消息后只是简单的打印了出来

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class VipUser implements Observice {

    private String id;
    private String username;

    @Override
    public void gotIt(Object s) {
        System.out.print("收到了推送:\t");
        System.out.println(s);
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.username;
    }

}

测试

在编写完后对整个流程进行测试

 public static void main(String[] args) {
        Service service = new MessageService();

        Observice user1 = new VipUser("1","小李");
        Observice user2 = new VipUser("2","小王");
        Observice user3 = new VipUser("3","小张");
        // 每个用户都进行订阅
        service.addSubscribe(user1);
        service.addSubscribe(user2);
        service.addSubscribe(user3);

        service.push("大家好,这是第一条推送");// 推送消息

        service.removeSubscribe(user2);
        service.removeSubscribe(user2);// 移除两次,会提示移除失败。

        service.push("大家好,这条推送没小王");

    }

结果如下

用户Id 1 姓名 小李 插入成功 
用户Id 2 姓名 小王 插入成功 
用户Id 3 姓名 小张 插入成功 
收到了推送:	大家好,这是第一条推送
收到了推送:	大家好,这是第一条推送
收到了推送:	大家好,这是第一条推送
所有消息推送完毕
用户Id 2 姓名 小王 已经移除 
用户Id 2 姓名 小王 不存在 移除失败
收到了推送:	大家好,这条推送没小王
收到了推送:	大家好,这条推送没小王
所有消息推送完毕

小结

通过这个小栗子可以初步的了解这种模式的设计,这样可以使用户和服务进行松耦合,用户可以随意的选择服务进行订阅,消息也可以精准的推送。


以下是代码存放的地址,没几个文件,萌新们可以一起来学习下。 [项目Demo地址](https://github.com/zza1998/java-mac/tree/master/src/main/java/com/zza/subscribe)

你可能感兴趣的:(随笔,java,接口)