Decision Matrix !
What is a decision matrix?
A decision matrix takes typically the form of a table, where we can list all the different options we may be evaluating at the time of designing an implementing a system.
Decision matrices are not only used for software architecture or development. They can be useful to any decision making process.
How exactly is a decision matrix useful?
For large systems that would require decoupling or decomposition to become more manageable and maintainable, as I mentioned already is the main objective of any micro-* architecture, we probably have multiple stakeholders, teams, and many problems to solve.
Putting together a decision matrix is a way to centralize the evaluation of the multiple solutions, and score them in a way that we can compare the results, and see the pros and cons of every one of the options discussed.
There are different ways to compare solutions. We can define a set of requirements or constraints and then use scores or weight, for each one of them, for each technology.
What could a decision matrix for micro-frontends, look like?
This is an example of the criteria that could be used to evaluate the different options for a micro-frontend architecture, although it could evidently be used for other use-cases, as well.
|(Sys) Non-functional requirements|
|Level of Encapsulation||N||N||N|
|Level of Decoupling||N||N||N|
|General learning curve||N||N||N|
|Quality of documentation||N||N||N|
|Quality of support||N||N||N|
|Quality of community||N||N||N|
|Quality of dev tools||N||N||N|
|XYZ feature support||N||N||N|
When is a decision matrix used?
A decision matrix is typically used by architects and developers during the discovery phase of a new or migration project.
You can learn more about becoming an architect and the different processes an architect participates of, in my post From developer to (solutions) architect. A simple guide.
I used three random options like 'Current or Monolith', 'Modular' or 'Decoupled', but you can use whatever amount and type of options you're evaluating, as long as they are of the same type: like frameworks, libraries, patterns, etc.
Some of the criteria I use in the example are more fit for architecture decisions. And some are more fit to compare technologies such as frameworks.
Types of requirement
In the matrix above I have made a distinction between criteria that map to system-wide constraints, at an architecture level, and critertia that may map to technical stack decisions.
We can put our decision matrix together from the perspective of functional and non-functional requirements, that satisfy business requirements, or the `why` we are building a system with decoupled frontends.
For example, a business requirement could be that we need to reduce the time to market for certain features of the application, like the e-commerce capability. If we need to make sure that the e-commerce has a faster iteration cycle, we may want to consider decoupling it.
As we can deduce from the matrix above, non-functional requirements apply to the whole system and are technology agnostic. They are tightly bound (kind of monolithic -pun intended-) to the business requirements.
For example, a non-functional requirement is to have global availabilty.
Functional requirements are those that define how the system will behave. Following the example I set before for a non-functional requirement, we can say that the functional requirement is to have a global e-commerce capability. This is when we start thinking about the pieces of the system, that will make sure that the e-commerce functionality is deployed closer to the user, and that's precisely when we make more technical decisions, like: We will decouple the e-commerce functionality, and deploy the business logic as serverless functions at the edge of the network.
When we understand the 'why', which means we have the business requirements defined, and the 'what', which means we have a clear idea of the functional requirements in our roadmap, we can start thinking about the 'how', or how we are going to make all this possible.
I am a great fan of making a lot of questions before making technical stack decisions. You can put down everything you want to expolore and evaluate, in your matrix.
For example the table below could give you an idea of how to layout a matrix to compare frameworks with capabilities we've seen in the frameworks section.
|Criteria||Framework A||Framework B||Framework C|
|Server Side Rendering||N||N||N|
|Integration with D (XYZ library)||N||N||N|
|Integration with E (XYZ database)||N||N||N|
And you can also use a matrix to compare the level of maturity of the frameworks community, ecosystem, documentation, etc.
It is advised to have different matrices per concern, so you can compare items in the same category. That will imply that sometimes you will need to aggregate data and results, from one matrix to another.
As you may have guessed, when we're evaluating potential solutions for composable architectures, we may need to create a matrix for non-functional requirements for each infrastructure component, instead of a system-wide one.
This is why architecture decision processes are not trivial and require a good level of experience. And they also require developers and architects to be objective and not biased by their own preferences, so they can effectively compare technologies with developer experience, developer productivity and business requirements in mind, yet also with user experience in mind.