訂閱發佈功能Java實現

前言

訂閱發佈最常見的就是在公衆號的訂閱,用戶訂閱了公衆號後,公衆號發佈消息時就能收到。其實他相當於設計模式中的觀察者模式

大致流程圖

在這裏插入圖片描述

用戶首先對感興趣的服務進行訂閱,該服務在發送消息時會將消息發送至所有訂閱的用戶。

實現

接口定義

使用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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章