According to Wikipedia, Software Architecture:
… refers to the fundamental structures of a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations.WIkipedia, https://en.wikipedia.org/wiki/Software_architecture
I heard on a podcast sometime ago that software architecture was the art of making as few decisions as possible.
When a software system is being designed, decisions have to be made about how to structure the subcomponents of the system. The ideal architecture allows the software developer to maintain a nice separation of concerns into clear and easy to maintain modules.
The architectural decisions made at the start of a project will have a major influence on how easily the project can be grown, maintained and ultimately, how well will it adapt changing requirements and technologies?.
So, how can we approach this challenge in the best possible way?
In essence, programming can be thought of as a series of abstractions over some concrete concept that the program is intended to represent.
In the case of myActivo, the concrete things are users, assets and physical measurements. We then have slightly more abstract concepts like KPIs, maintenance tasks, asset condition, likelihood of failure and criticality. As we keep building on these abstractions, we ultimately make decisions about what to do with a specific asset. Should we maintain it? replace it? refurbish it? let it fail?
We have to somehow represent all these concepts in software and enable the interaction of data and algorithms. A successful software platform should unlock value from these assets which we could not otherwise realise. It should enable the user to gain insights about the behaviour of a system and make better and more informed decisions with ease.
In his post about the ladder of abstraction, Bret Victor reflects:
How can we design systems when we don’t know what we’re doing?Bret Victor, Up and Down the Ladder of Abstraction
In the context of myActivo this translates to the question of, how do we setup
How to we design a system that adequately represents concrete concepts whilst making the necessary abstractions to flexibility to adapt to new requirements and concepts?
Over the years, many architectural patterns have been proposed and refined by the programming community.
With so many options on how to structure myActivo it was difficult to land on something I felt would be the right balance of complexity and practicality of the implementation.
After careful consideration (and a couple of glasses of Pinot Noir) I decided to go with the principles of Clean Architecture and Microservices.
In his 2012 blog post, Robert C. Martin (a.k.a. “Uncle Bob”) proposed the concept of the Clean Architecture.
In this article, Martin lays out the principles that, if followed, would lead to a maintainable code base.
The key to this architecture is the direction of the dependencies indicated by the arrows on the diagram below.
The direction of these dependencies mean that components of the system that are more likely to change over time, like the User Interface (UI) for example depend on components that are less likely to change, like the use cases or business entities.
If the dependencies were the other way around, a large amount of effort would be necessary to change the UI implementation being used for example.
Similarly to the Clean Architecture principles, Microservices represent an architectural paradigm in which the system is designed to be a collection of modules with the right level of granularity and responsibility that make up a more complex application.
A set of principles in software development called SOLID favour the creation of single-responsibility modular software components that should be easy to modify as the need arises in the future.
In general, these principles intend to move the developer away from creating a “monolithic” application, which proves harder and harder to sustain as the complexity and number of features implemented in the system grow.
With these two sets of principles in mind, I will try to implement a platform that follows the Clean Architecture and Microservices philosophies.
My immediate question was, what is the best way to combine these two architectural patterns?
I’m sure that I will learn a lot by the mistakes I make moving forward, but as of the time of writing this post I think the best way to combine these can be represented by the diagram shown below.
In this architecture, I would define the core entities (we’ll talk about what these are in future posts) in a single project.
Following the Microservices philosophy I will then implement a microservice for each of the five core modules of the Digital Asset Management framework.
Each of these modules will implement the core logic for each of its use cases and provide its services in the form of a well defined set of Application Programming Interfaces (APIs).
Finally, the User Interface (UI) will “glue” all these together into a cohesive and, hopefully, pleasant user experience.
I have decided that I will work through the implementation starting with the UI and then move towards the deeper layers of the system.
As always, I welcome your comments and suggestions.