Event Proxy - Design Pattern
Explicitly express outside event in your domain model, regardless of how it's delivered; make delivery mechanism an implementation detail.
When outside event is the reason of an action within the system at hand, it's important not to be distracted with the specifics of the event delivery between the systems. If domain experts mention specific condition as an event, we should express it as an event in our domain model too. However, often outside systems don't support push notifications to send to our systems, so the notion of the event can get lost into the paradigm of data polling or other interaction styles. This deviation from the original event concept creates problems long run, such as:
- Most importantly, event is not expressed as being an event in our system, even though it is understood as an event by domain experts, not as data retrieval. So our model becomes implicit and not in-line with the experts. This will add to the burden of translating communication between domain experts and software engineers implementing the model.
- If outside system implements the event pushing mechanism in the future, we will have to rebuild our model, even though it should have been just an implementation detail from the beginning. Had it been so, we would have to only rebuild the implementation details, and not the model. Many people will argue that they would not design the model for the future (YAGNI), but that is just a denial of the Open-close principle at least. You need to find the tradeoff by just making the event condition as an implementation detail.
Event Proxy is the extension of the Proxy design pattern, with the event defined on it. In some cases, actual outside system may not offer such an event at all. That fact is hidden from the Event Listener since it's only dealing with the Event Proxy, and thus subscribing to the event exposed by the Event Proxy. Event Proxy in turn decides when to fire the event depending on the implementation of the outside system. If a push style event notification is available, then Event Proxy simply subscribes to the event of the outside system, and then fires its own internal event to the Event Listener in an answer to the outside event. If the outside system does not support a push style event notification, then Event Proxy may resort to other primitive mechanisms, such as polling the data every now and then, until the condition is met. Once the condition turns positive, Event Proxy fires the event to the Event Listener.
Implementation of the actual event delivery from outside system to the Event Proxy becomes irrelevant to the implementation of the Event Listener. By adding an interface of the Event Proxy to our domain model, alongside with the Event Listener, we explicitly express our intention to react to the outside event, regardless of how it's been delivered between the systems.