We’ve got a spaghetti mess of an application that I’ve been tasked with rebuilding. I really want to make the new code much more flexible, and also more distributed.
On a basic level the application collects data from hardware, performs some control actions, displays the data, and lets the user send settings to hardware.
There was no separation, the code was hardware specific, no data access layer/disconnect between data, backend, control, and eventually UI. It was a horrible mess when we had a hardware change, and everything had to be reworked. It was also a single application on a single computer, yet we need it to be more modular. Maybe one server collects data and makes local control decisions etc, and when it has a link uploads that to a central database.
I’m trying to come up with some architecture/design patterns that will help with this and I’ve seen Event Aggregator come up a lot. However, it seems mostly aimed at the UI side of things, whereas I’m thinking of a cross-service/application messaging.
Does this sound like a sensible design? Does it sound like any design patterns out there? I don’t want to re-invent the wheel.
The main principle of event agragators, that the source and consumer of the events know nothing of each other seems like it could be difficult to achieve when they don’t share an application.
I think you are on the right track with Event Aggregator.
Consider the alternative which is Observer pattern and you realize that there are multiple sources of hardware events that one must have handling logic to observe on and make decisions. Martin Fowler does a better job than I do about explaining the advantages of Event Aggregator here.
Also consider all of the important Quality Attributes of your system and allow those most important attributes to drive your architectural decisions here.
A message driven architecture utilizing Event Aggregator pattern can address the consolidation of messages being created from components and do a number of things with this.
- One option is that if this data must be persisted, it makes sense to transform the message into a common data format and persist in a data store/file/database. Another Service component can read data from the database for reporting and status
- Another option is that the aggregator component can instead publish a message to a Topic in a common format and multiple recipient components subscribing to that Topic will receive the message and choose to potentially store data in their own store or do something else with the data entirely in real time. Information on Topics http://activemq.apache.org/how-does-a-queue-compare-to-a-topic.html
I see the Hardware abstraction software components sending unprocessed data messages to a Remote Queue. These messages all transmit to a Local Queue that the Aggregator component will listen on for incoming messages. It can then transform the data into a common format and either publish a message to a topic or save the data in a database. This Aggregator could also optionally handle sending messages in the opposite order via different messsage queues to various Hardware abstraction components for configuration changes. You could also have a separate Aggregator component and process to handle this use case.
Now you can build services against your database for read data requests, and against a message queue for incoming configuration changes.
This gives you separation of concerns, easier modularity when standing up software components, ease of maintainability and abstraction from hardware changes, and greater flexibility on the GUI side to have multiple types of user interfaces (Desktop application, web application, mobile, etc…).