Architecture Pattern:publish-subscribe Pattern

Source: Internet
Author: User

1. Brief

has been confused with observer pattern and pub/sub pattern, the following plan through the two blog to comb these two patterns. If there is a mistake, please correct me.

2. Role

Publisher: A message publisher that assembles the original message entity and triggers the body of the message delivery.

Subscriber: A message subscriber that receives a message entity and responds to the principal.

Message Broker or Event Bus: A medium between a messaging publisher and a message subscriber, which contains message filtering and message routing capabilities, and can be processed through the built-in message queue's real-world priority.

The filtering function is subdivided into two types of topic-based and content-based.

Topic-based is to establish a separate channel for the message subject, and Subscribers subscribing to a particular topic will receive the message via the corresponding channel;

Content-based is the message content as the processing source, the Subscriber receives only the message content and the target keyword matches the message.

In addition, hybird=topic-based and content-based can also be used.

3. Advantages

 1. Loose coupling

With the introduction of message broker to handle features such as filtering and routing of messages, Subscriber is also subscribing to messages through Messsage broker, resulting in low coupling between publisher and Subscriber. This low coupling is reflected in two aspects.

Space: Publisher and Subscriber can run on two different processes, even on machines;

Time: Publisher and Subscriber do not have to run at the same time through message broker staging messages (Store and forward) and implementing asynchronous processing of messages.

 2. Scalability

Because Publisher and Subscriber are loosely coupled in space and time, we can increase processing power by increasing the process/machine approach.

4. Disadvantages--semantic coupling

  "The most insidious kind of coupling occurs when one module makes use, not of some syntactic element of another module, BU T of some semantic knowledge of another module ' s inner workings "--chapter 5 of Code complete

semantic coupling (Semantic coupling)is a kind of obscure coupling type, which leads to the main reason of code refactoring, debugging and modifying complexity increasing rapidly.

Types are as follows:

1. Operation Order coupling: With an object, init () needs to be called before doanything () can be called. This sequential coupling, even remark in the document is extremely elegant;

2. Global parameter passing: module A modifies a global parameter g_val, and Module B reads the value. Module B must know that module A has already assigned a value to the parameter;

3. The business package is not tight enough: module A passes a parameter to Module B, and Module B selects the corresponding operation according to this parameter. Module A must know all the operation types that are related to the business. For module A, only the semantics that the module a itself can understand, or the popular concept as a parameter, rather than the encapsulated business-related parameters;

4. Data type conventions beyond the interface: module A passes a pointer to module B for an interface, and Module B casts it as a pointer to a derived class. When module B knows the actual type of the interface, the encapsulation has been compromised. A non-related module can operate on an interface only, not on responsibilities outside the interface.

 Public Interfacecustomer{} Public classvip:customer{ Public voidServe () {}} Public Static voidMain (string[] args) {Customer customer=NewVIP (); Serve (customer);} Public Static voidServe (Customer customer) {VIP VIP=(VIP) customer; Vip. Serve ();}

5. Simple implementation

/** * @class * @private * @description Help class*/classutils{/*@method Processing of filter input by user * @static * @package * @param {domstring| function} Origfilter-the user outputs a filter * @returns {Function} * @exception*/        StaticWrapfilter (origfilter) {varType =typeofOrigfilterif('string'= = = Type)returnMessage = REGEXP (Origfilter,'I'). Test (Message.topic)Else if('function'= = = Type)returnOrigfilterThrowError ('the type of argument (0) is wrong, which accepts string or function instance only!')        }        /*@method Add message to Message queue * @static * @package * @param {array.<message>} MQ-Message Queuing * @ param {Message} message-instance of messages added*/        Staticaddmessage (MQ, message, timer) {Timer.pause=1                if(! (Timer.pause = mq.length))returnmq.push (message) for(vari =0, inserted =0, M;!inserted && (M = mq[i]); ++i)if(inserted = M.priority <message.priority) Mq.splice (i,0, message)if(!inserted) Mq.push (message) Timer.pause=0        }        /*@method Distribute messages to subscribers * @static * @package * @param {array.<message>} MQ-Message Queuing * @p Aram {Array} Subs-Subscriber pool * @returns {array.<message>}-Message Recycling queue not responding*/        StaticDispatch (MQ, subs) {varmessage, UNRESPONSEDMQ = []             while(Message =Mq.shift ()) {Let found=0                     for(Let sub of subs)if(found =sub.filter (message)) {sub.handler (message) Break                    }                    if(!found) unresponsedmq.push (message)}returnUNRESPONSEDMQ}}/** * @class * @private * @description Message Class*/classmessage{Constructor (topic, content, priority=0){                 This. Topic =Topic This. Content =content This. Priority =Priority }}/** * @class * @public * @description message broker. B (Roker)*/Exportdefault classmrb{Constructor (during=Ten){             This. MQ = []             This. Subs = []            //Dispatch message to subscribers, then recycle unhandled messages             This. Timer = {Timer:setinterval () ={                        if( This. Timer.pause)return                         This. MQ = Utils.dispatch ( This. MQ, This. Subs)}, during)}}/*@method Subscription Message * @public * @param {domstring| function} Filter-Message Filter * @param {function} handler-message response function*/Sub (filter, handler) { This. Subs.push ({filter:Utils.wrapFilter (filter), Handler:handler})}/*@method Post Message * @public * @param {domstring| Object| Message} topic-messages subject or message entity * @param {domstring} [content= ']-message content * @param {number} [priority=0]-Message Excellent First Class*/Pub (topic, content="', priority =0){                varmessageif(1= = = arguments.length) message = (topic.priority = topic.priority | |0, topic)ElseMessage =NewMessage (topic, content, priority)//push message to MQUtils.addmessage ( This. MQ, Message, This. Timer)}}

6. Caution

1. The pub/sub mode is one of the messaging modes, while the messaging mode is a network-based architecture pattern (network-oriented architectural pattern), which means that cross-process communication is the application scope Whereas the Observer mode is a design pattern based on object events (Object-event oriented pattern), and its application is within a single process.

2. Pub/sub mode is suitable for non-real-time processing;

7. Idea

In the development of the page I prefer the development of Component-driven Dev mode, the surface is to cut the page as a function of independent components, essentially the problem-dependent cohesion, so as to better identify and solve problems. Communication between components is another issue that must be taken into account when using this development model. There are a lot of solutions, but I think the basic principles should be:

1. Since the components are loosely coupled structures that are independent of each other, communication between them should not lead to a side effect of increased coupling; (if communication between components is tight, consider whether developing sub-components is more appropriate)

2. The communication channel between components should be configured so that the data flow can be processed flexibly. (e.g. write log, data conversion, type conversion, etc.)

In the Pub/sub mode, the message broker is responsible for the filtering and routing of information, and realizes the flow of messages between components by using the messages as the data carrier for communication between components. You can also implement a custom component communication channel by customizing message Broker to implement basic service functionality in an AOP manner.

Inevitably, this approach introduces new problems:

1. Message broker has an asynchronous processing feature as a messaging hub, which needs to be introduced in another way if it needs to be executed synchronously;

2. Due to the loose coupling between components, the message flow path must be recorded in a good logging mode, otherwise it cannot be debug.

8. Conclusion

Respect the original, reprint please specify from: http://www.cnblogs.com/fsjohnhuang/p/4624566.html ^_^ fat son John

9. Thanks

Https://en.wikipedia.org/wiki/Messaging_pattern

Https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern

Http://stackoverflow.com/questions/11857325/publisher-subscriber-vs-observer

Https://en.wikipedia.org/wiki/Store_and_forward

Architecture Pattern:publish-subscribe Pattern

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.