The Clean Architecture Approach to Looking at the Model
Clear up a common architectural mistake with MVC, MVP, MVVM.
These are the classic layered architecture patterns that many people are familiar with. What do the arrows in the diagram represent?
If you think the arrows represent the flow of input & output, you are correct! However …
The arrows in these architecture diagrams do not represent the dependency flow .
This is the most common mistake people make when they look at these architecture diagrams. It is also the start of the misconceptions around the dependency rules with the model component.
Dependency Inversion Principle
The dependency inversion principle(DIP) is a tenet of SOLID. Here’s the Wikipedia definition.
1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).
2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
To simplify the concept in the words of Uncle Bob,
In a good architecture, the direction of those dependencies is based on the level of the components that they connect. In every case, low level components are designed so that they depend on high level components
Here’s the flow diagram in a way that shows where the components fall in terms of level.
The input/output flow points up to the model and then back down to the view. Does that mean the dependencies also follow the same trend?
Does the model know about the presentation component?Does the presentation component know about the view?
Let’s look at this from a policy & detail perspective.
Policy and Detail
You can describe software as a collection of policy and detail. Policies are the rules of the business. They represent the core concepts and actions of the business. The detail is the implementation of the policy. These two concepts are closely related to describing components as low-level and high-level.
To give an example of policy and detail, let us pretend that we have a business that enables users to set up an online store to sell T-shirts. I would create business entities to represent key concepts like T-shirts, customers, and stores. The code representation of these concepts should be platform-agnostic. The detail comes in when we implement Android/iOS/Web apps. Which database do we use on each platform? What’s the communication protocol between the clients and data providers? What will the store view look like? That’s the detail.
Back to architecture. This is what our architecture dependency diagram looks like in the eyes of policy and detail.
Notice that the dependencies only point up? That’s the dependency inversion principle at work! The model should not depend on any components below it. This keeps the model components decoupled and reusable.
The Impact of Dependencies
Risk and volatility scale up as we introduce more dependencies to a component. The height of the component in the policy-detail spectrum correlates with the likeliness or frequency that code will change.
Between a T-shirt data class or the view that displays the T-shirt details, what is more likely to change over time?
The dependency inversion principle establishes a sensible dependency flow that encourages higher-risk components to depend on lower-risk components. It should never be the other way around.
Closing Thoughts
Check out my article on Maximizing The Leverage of Architecture for a better look into where design patterns fit in the policy-detail spectrum.
Be mindful of the dependency inversion principle and the number of dependencies a component has.
Understanding all these concepts will guide you in writing better software.