John was assigned with user registration issue. He wanted to avoid this issue, because of complexity level that was related to this code. He was working in the project for two years and he was already fixing it for several times, however whenever he opened the code, it was like he would see it for the first time.
John was picking any other issue, delaying the registration problem to the last possible minute. He was sweating, whenever his supervisor was asking about the issue. So after several days, he decided to refactor the code, to make his work easier.
Have you ever worked on the code that was doing so much, that it was scary to change it?Or have you analyzed it from the beginning whenever you opened it?
This often comes from the code full of Sub Flows, which have been merged with the Main Flow.
Main Flow and Sub Flows
In case of the registration Main Flow would be creating an user and saving it to the database.
The Sub Flows on other hand could be:
- Sending an welcome or confirmation email
- Creating audit logs about user registration
- Synchronizing registered user to external Service
If we will look on registration (creating and saving the user) as the main flow, the sub flows happens as a result of main flow being successful.
So how do we tell that the main flow was successful?
We are doing it by Events!
Event is describing that something happened in the past. In case of the registration it would be that User Was Registered.
By subscribing to Event, we are able to run any Sub Flow.
Publishing and Subscribing to Event
Let's start by defining Event Class.
The Event is class clear of any framework related interfaces or abstract classes.
We will publish the PersonWasRegistered event using Event Bus from PersonRegistrationService.
The Event Bus is automatically registered in Dependency Container after installing Ecotone
We can now move all the logic to Event Handlers, which subscribe to specific event.
The Event Handler subscribes to specific event based on first parameter type hint.
We have used a single class here that contains of three Event Handlers.
You are free to create separate classes for each Event Handler, if you feel the need.
You could notice, that we are injecting specific Service directly into Event Handler's method.
This is possible due to Ecotone's Method Invocation mechanism. You may pass any services to given Command/Event/Query Handler's method, and Ecotone will do the work by injecting those services for you.
John is sure now, that separating sub flows will make his code more readable, testable and solid.
He sees that changing the code for given functionality will only affect given flow now.
He can think of much easier testing as he can test Event Handlers separately and in isolation.
And is sure, that it will be easier for the team to maintain the code in the future when new sub flows will arrive.
If you want to read more about Event Handling, follow the Ecotone's documentation.