《設計模式》--發佈訂閱模式

發佈訂閱模式

該模式主要涉及三個類型對象: 發佈者、發佈訂閱管理器、訂閱者;

設計原理 

   發佈者將消息發佈到管理器上, 訂閱者從管理器訂閱消息;這樣將發佈者和訂閱者進行了解耦,實現了鬆耦合;

實現代碼實例

 1、發佈者

package com.jt.designModel.subscriber;

public class PublisherImpOne<T> implements Ipublisher<T> {
    
    private String name;
     
    public PublisherImpOne(String name) {
        super();
        this.name = name;
    }
    @Override
    public void publish(SubscribePublish<T> subscribePublish, T message, boolean isInstantMsg) {
        
          subscribePublish.publish(this.name, message, isInstantMsg);
    }
    

}
 

2、管理器

package com.jt.designModel.subscriber;

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

public class SubscribePublish<T> {
    //訂閱器名稱
    private String name;
    //訂閱器隊列容量
    final int QUEUE_CAPACITY = 20;
    //訂閱器存儲隊列
    private BlockingQueue<Msg<T>> queue = new ArrayBlockingQueue<>(QUEUE_CAPACITY);
    //訂閱者
    private List<ISubcriber<T>> subcribers = new ArrayList<>();
 
    public SubscribePublish(String name) {
        this.name = name;
    }
 
    public void publish(String publisher, T message, boolean isInstantMsg) {
        //true  
        if (isInstantMsg) {
            update(publisher, message);
            return;
        }
        Msg<T> m = new Msg<T>(publisher, message);
        if (!queue.offer(m)) {
            update();
        }
    }
 
    public void subcribe(ISubcriber<T> subcriber) {
        subcribers.add(subcriber);
    }
 
    public void unSubcribe(ISubcriber<T> subcriber) {
        subcribers.remove(subcriber);
    }
 
    public void update() {
        Msg<T> m = null;
        while ((m = queue.peek()) != null) {
            this.update(m.getPublisher(), (T) m.getMsg());
        }
    }
 
    public void update(String publisher, T Msg) {
        for (ISubcriber<T> subcriber : subcribers) {
            subcriber.update(publisher, Msg);
        }
    }
}
 
class Msg<T> {
    private String publisher;
    private T m;
 
    public Msg(String publisher, T m) {
        this.publisher = publisher;
        this.m = m;
    }
 
    public String getPublisher() {
        return publisher;
    }
 
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }
 
    public T getMsg() {
        return m;
    }
 
    public void setMsg(T m) {
        this.m = m;
    }
}

 3、訂閱者

package com.jt.designModel.subscriber;

public class SubcriberImpOne<T> implements ISubcriber<T> {
    
    public String name; 
    public SubcriberImpOne(String name) {
        super();
        this.name = name;
    }
    
    @Override
    public void subcribe(SubscribePublish<T> subscribePublish) {
        subscribePublish.subcribe(this);
        
    }

    @Override
    public void unSubcribe(SubscribePublish<T> subscribePublish) {
        subscribePublish.unSubcribe(this);
        
    }

    @Override
    public void update(String publisher, T message) {
          System.out.println(this.name + "收到" + publisher + "發來的消息:" + message.toString());
        
    }

}

4、測試類

package com.jt.designModel.subscriber;

public class Test {

    public static void main(String[] args) {
        
        SubscribePublish<String> subscribePublish = new SubscribePublish<String>("訂閱器");
        
        Ipublisher<String> publisher1 = new PublisherImpOne<>("發佈者1");
        Ipublisher<String> publisher2 = new PublisherImpOne<>("發佈者2");

        ISubcriber<String> subcriber = new SubcriberImpOne<String>("訂閱者1");
        subcriber.subcribe(subscribePublish);
        
        // 發佈消息
        publisher1.publish(subscribePublish, "welcome", true);
        publisher1.publish(subscribePublish, "to", true);

        
      publisher2.publish(subscribePublish, "你好", true);
        
    }

}
 

5、測試結果

 訂閱者1收到發佈者1發來的消息:welcome
訂閱者1收到發佈者1發來的消息:to
訂閱者1收到發佈者2發來的消息:你好

總結 

   發佈訂閱模式, 主要是通過訂閱器達到和發佈者之間的鬆耦合關係;該模式可用在消息推送類型的場景;在我所在的項目中, 由於數據庫表存在冗餘的消息, 在更新基礎表信息時,需要將冗餘的信息同步更改。 也可以採用該模式;在分佈式項目中,也可以採用消息中間件 來實現多個項目的一致性。 

  該模式和觀察者模式之間的區別, 主要的區別就在於,是否存在 管理器;觀察者模式中, 觀察者和發佈者之間存在耦合, 即觀察者需要註冊到發佈者對象上, 這樣,發佈者在發佈時, 會執行觀察者的相應方法;下圖藉助於網上,能夠比較清晰的區分這兩種模式的區別:

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章