文章目錄
- 發布訂閱概念
- 發布訂閱 vs 監聽者
- 例子代碼
發布訂閱概念
發布/訂閱者模式最大的特點就是實現了松耦合,也就是說你可以讓發布者發布消息、訂閱者接受消息,而不是尋找一種方式把兩個分離 的系統連接在一起。當然這種松耦合也是發布/訂閱者模式最大的缺點,因為需要中間的代理,增加了系統的復雜度。而且發布者無法實時知道發布的消息是否被每個訂閱者接收到了,增加了系統的不確定性。
發布訂閱 vs 監聽者
參考文章:https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c, 理解發布訂閱模式和觀察者模式的區別
Let’s list out the differences as a quick Summary:
-
In the Observer pattern, the Observers are aware of the Subject, also the Subject maintains a record of the Observers. Whereas, in Publisher/Subscriber, publishers and subscribers don’t need to know each other. They simply communicate with the help of message queues or broker.
-
In Publisher/Subscriber pattern, components are loosely coupled as opposed to Observer pattern.
-
Observer pattern is mostly implemented in a synchronous way, i.e. the Subject calls the appropriate method of all its observers when some event occurs. The Publisher/Subscriber pattern is mostly implemented in an asynchronous way (using message queue).
-
Observer pattern needs to be implemented in a single application address space. On the other hand, the Publisher/Subscriber pattern is more of a cross-application pattern.
發布訂閱解偶,通常使用消息中間件,能實現跨平臺、異步通信
例子代碼
- 發布者發布消息
public interface Publisher {// 發布消息void publishMessage(String msg);}
- 訂閱者訂閱并響應消息
public interface Subscriber {// 進行訂閱void subscribe();// 響應消息void onMessage(String message);
}
- 第三方中間件做消息中轉并通知訂閱者
public class Broker {List<Subscriber> subscriberList = new ArrayList<>();List<Publisher> publishList = new ArrayList<>();List<String> messageList = new ArrayList<>();public void notifySubscribers(){while(!messageList.isEmpty()){String message = messageList.remove(0);for(Subscriber subscriber :subscriberList){subscriber.onMessage(message);}}}public void publishMessage(String message){messageList.add(message);}public void subscribt(Subscriber subscriber){subscriberList.add(subscriber);}public void publish(Publisher publisher){publishList.add(publisher);}public static void main(String[] args) {// 發布訂閱中心, 消息中間件一樣Broker broker = new Broker();// 發布者注冊Publisher1 publisher = new Publisher1();publisher.setBroker(broker);// 訂閱者注冊Subscriber1 subscriber = new Subscriber1();subscriber.setBroker(broker);subscriber.subscribe();// 發布者發布消息publisher.publishMessage("hello");// 中間間會通知所有訂閱者broker.notifySubscribers();}
}