|HOME PATTERNS RAMBLINGS ARTICLES TALKS DOWNLOAD BOOKS CONTACT|
What is in a Name?
Mar 5, 2006
A New Element
Messaging-based interaction introduces two new elements, a channel and a message. Despite their simplicity these new elements open up options and force new decisions. A deceivingly simple question is “how should the channel be named?” When one method called another directly there was no intermediate element and therefore no decision to make. Now that we afforded ourselves the new level of indirection we have to name it appropriately. Choices, choices...
More Than Just a Name
In order to find an appropriate name for a channel we need to first determine what the channel should represent. Even though a channel can be a purely logical construct, it is the key mechanism that couples sender and receiver. Both sender and receiver of messages have to agree on a common channel name in order to exchange messages.
Let's look at a few obvious choices:
Communicating through events as opposed to commands indicates a subtle but important shift of responsibility. It allows components to be decoupled to the extent that the “caller” is no longer aware of what function is executed next nor which component is executing it. Another equally important shift of responsibility between caller and callee is that of keeping state.
In a system that is based on queries and commands state is usually kept in one application that is considered the “master” for the data. When another application needs to reference that data it sends a query to the owning application and waits for the response before it continues processing. For example, when an order management system needs to fulfill an order it queries the customer management systems for the customer’s address so it can instruct the shipping application to send the shipment to that address.
Event-driven systems work differently, almost to the inverse. Systems do not query other systems for information but instead keep their own copy of the required data and listen to updates as they occur. In our example this would mean that the shipping system keeps its own copy of the customer’s address so when an order arrives it can use that address to label the shipment without having to query the customer management system. While replicating data this way might seem dangerous it also has advantages. The customer management system simply broadcasts changes to the data without having to know who all keeps a copy. Because the customer management is never queried for address data it never becomes a bottleneck even as the system grows and the demands for address data multiply.
The principle behind the shift in responsibility is once again tied to the concept of coupling. In a loosely coupled interaction a source of data should not be required to keep state at the convenience of its communication partners. By shifting the burden of keeping state to the consumer the component is can be completely oblivious to the needs of the data consumers – the key ingredient into loose coupling. The shift away from the query-response pattern of interaction means that many components have to act as event Aggregators: they listen to events from multiple sources, keep the relevant state and combine information from multiple events into new events. For example, the shipping system effectively combines address change events and order events into request for shipment to a specific address.
It sounds like event-based systems surpass command-and-control systems across the architectural "score card". They are more loosely coupled and allow free composition of individual components into a larger system, thus aiding reuse and flexibility. Additionally, they can provide a natural mapping of a problem space into the system model. After all, many interactions in the real world are based on events. So are non-event-based systems for losers? Not quite -- as always, there is not free lunch, at least outside Google. Dynamic, loosely coupled systems are inherently difficult to design and debug (see Good Composers are Far and Few in Between). So we need to make sure to have the right tools at hand (for example, see Visualizing Dependencies) and to gain experience by making mistakes early in a small scale.
|© 2003-2019 • All rights reserved.|