Build Simplicity into a System with Simple Event-Driven Components
Use events for interactions between small business components to bring simplicity to a system, Russ Miles recently suggested talking about Coding Simple Event-Driven Components for Agile Software.
This talk is a follow-up on his talk a month earlier, Events bring Simplicity to a System's Architecture, where Russ laid the foundation for his ideas about simplicity; an architecture where small components collaborate with each other by exchanging events.
The aim for Russ using this design is to get components in such a situation that they can change at the rate the application or system should change, and to get rid of the friction of change where a small change will mess things up.
In his recent talk Russ focuses on the components, and uses simplicity as a principle to reduce coupling between them. Is a component easy or not? A good test is how easy it is to move the component. If a move is hard that’s a good indicator that the component is too complex. He compares moving a complex component with a bucket of Christmas tree lights, you pick one and everything comes with it.
To simplify a complex component, he first breaks out concerns and side-effects, moving these into new smaller components or functions. An example of a side-effect is integration with the outside world, e.g. logging which Russ sees as a concern that should be moved into the infrastructure.
Events is the mechanism for transferring data between components. This leaves a location coupling between components since the sending part needs to know the receiving part, but that is removed by introducing an intermediary event domain with an event dispatcher.
The easiest form of events is a shared immutable class that is moved from one component to another, but that also introduces coupling. The next step for Russ in reducing complexity is replacing this class with data in the form of named parameters, e.g. maps of key-value pairs.
The negative side of this design is indirection; Russ believes it’s not more complex, but postponing some of the potential problems that may show up. The answer to this is extensive testing, both unit tests and integration tests, (between two components).
Using key-value instead of immutable class
I do think that event should be well structured since it is a contract like any other interface. Replacing this contract with a loose key-value structure only creates more uncertainty that Russ is trying to solve with integration tests between two components, acknowledging the fact that the two components have dependency.