I decided to talk about the architecture choice I take when developing my apps!
Not long ago, I have been asked the following by fellow developers:
How do you structure your projects because when they evolve, the basic n-tier architecture becomes more complex and they tend to create messy solutions.
I don't have all the answers but what I actually said is that when it comes to my own projects, I make a simple choice:
- If I am working on a basic CRUD app, I will definitely go for a 3-Tier architecture.
- But if I need to build a more complex app requiring a strong business logic and which must scream its goal, I will definitely use what Robert C. Martin called the Clean Architecture in 2012. Of course, my version is not strictly following what Uncle Bob describes in his blog as I have tailored it to my needs but let's talk about it.
Nowadays though, I tend to be more inclined to use the latter. But what does the Clean Architecture bring me that I love and that n-tier does not?
The N-Tier architecture
What is it?
First of all, it would be a shame to talk about the Clean Architecture and not talk about what I have learnt during my years at school: the n-tier architecture. This type of architecture is usually presented as and mixed up with one of its specific version: the 3-tier architecture.
This architecture places the data as the core of the application. The 3 layers are:
- the presentation layer, responsible of presenting the information to the outside ;
- the logic layer, responsible of the business logic that should be applied on the data ;
- the data layer, responsible of the data access.
Of course, the "n" in the name means that you can actually have less or more than 3 tiers. The layers described above are just the common ground. There are other types of comparable structures like the 2-tier architecture, the single tier, the 4-tier ... When developing a project, you usually tailor the architecture to your needs. You could even subdivide the 3 common layers into sub-layers depending on your requirements.
Pros & Cons
For the advantages, we can list the following:
- more secure — The presentation layer (usually the UI or such) is not "directly" wired to the database. All connections to it are shielded by the logic layer.
- easily maintainable — at the time of its "creation", this archi allowed the developers to maintain it much more easily than the previous architectures did.
- easy to reuse — it is easier to reuse the logic of each layer.
For the disadvantages, let's have a quick look too:
- increase in effort — implementing new features takes time as you have to go through all tiers. Changing a single thing in the database layer is reflected to the logic and presentation layers as they directly rely on it.
- increase in complexity — when it grows, it becomes more difficult to keep it clean, understandable and predict the impact of a change.
- harder to test — implementing tests is quite difficult as everything is highly coupled to the layer it points toward.
When to use it?
In my humble opinion, using the n-tier architecture is a good start when you need to develop the prototype of an idea because you need to showcase something quickly. This will unfortunately tend to make things less great for the future though.
You could also use this archi when you need to build an easy CRUD app. Speaking of such, it is often used when you simply want to query a database. I once did that for one of my employers.
The Clean Architecture
What is it?
This architecture puts the Domain at the center, and in charge of everything. It also requires more intentional designs as you do not rely on your database directly. Built with the CQRS pattern, I consider it the best way to write a software with maintainability and simplicity in mind.
Historical fact: the 3-Tiered architecture came in 1992 thanks to John J. Donovan and was followed by others afterwards:
- Hexagonal Architecture / Ports & Adapters (2005, Alistair Cockburn),
- Onion Architecture (2008, Jeffrey Palermo),
- Clean Architecture (2012, Robert C. Martin).
Pros & Cons
For the advantages, we can list the following:
- less coupled code, better testability — as the code is less coupled due to using abstractions everywhere you can, you can easily mock dependencies and unit test your components. It also facilitates the development in each layer as they are not highly coupled together, allowing teams to work in parallel on each layer.
- separation of concerns — the architecture kind of forces you to think about your use cases and dependencies. The UI also does not care about how your database looks, nor does it care about the packages you use to generate a PDF for example...
- better features exposition
- better application of SOLID principles
- better evolutivity
For the disadvantages, we can list the following:
- increase in time to build from scratch — you need to setup more things before starting to develop a valuable feature for the client.
- increase in code — you need more files (classes and interfaces) than in an n-tier architecture.
- possible loss of optimization — being closer to implementations might grant you better performances. You would lose this in profit of looser coupling which IMHO is a good trade-off.
Editor's Note: Honnestly, reading this again... I don't feel like these are real disadvantages. They can be easily overcome with experience, and will make you gain time on the long run, especially if you decide to work with tests (which you should if you want to produce good code!).
When to use it?
When you need to develop a complex software, that you want to test your features and want to deliver something valuable that will not increase the buglog once in production. It can also be mixed with methodologies that make it a strong reliability like DDD and TDD.
So why do I prefer CA over N-Tier?
You might know now but I am tired of developing crappy things, I'm tired of working in a company where you get told to "develop fast and we will improve it later". Later never comes.
I am so tired of such way of working that I fell in love with 3 things:
- Clean Architecture, and
- Test-Driven Development, and
- Software Craftsmanship.
But more seriously, I haven't explained why I like it... In a few words, let me tell you. You need to know that developing an application without tests, it's like developing with your eyes closed: you do mistakes. I then started digging this part of my job I was neglecting at the time: testing. Thanks to my professional experience at Pwc Luxembourg, I met wonderful people who taught me a lot of new things.
That was when I've been asked to write an application following a particular architecture... And everything got solved once I practiced.
Developing with Clean Archi, for me, it is the real culmination of software development where the technical "parts" can finally be changed without having to rework something else. The truth is, I learnt so much with Clean Architecture:
- I understood the real deal that Dependency Injection represents ;
- I succeeded in applying SOLID principles better than all the other times I tried, in vain ;
- I understod that I had to name my interfaces independantly of the implementation that could ensue from it since I could potentially have 3 different implementations of
- I understood that testing is fun ;
- I understood that writing apps without bugs is possible and should be common.
And I went to IT school! They explained what dependency injection, SOLID principles, clean code... are, they taught me how to prepare for a development and avoid the majority of bugs... But that doesn't mean I haven't written horrible code or buggy apps or patched a feature and broken something else in the process.
So, I highly encourage you to learn more about these 3 topics I listed above. The rest should come... They represent what I would love to call the best mindset for the next generation of developers.
I would also recommend to learn more by looking at the following resources:
- The presentation of Guillherme Ferreira on The Grand Unified Theory of Clean Architecture and Test Pyramid at NDC Porto ;
- Valentina Cupać's slides about TDD and Clean Architecture driven by behaviour ;
- A blog post relating an introduction to CA ;
- The example of such structure that is Jason Taylor's Clean Architecture Template!
What finally makes the n-tier architecture obsolete is that it is actually data-centric unlike the clean archi that is domain-centric (logic). It took us time to understand that what gives value to our clients is not the data, but the business logic that allows to process that data!
If you are still interested in learning more on the topic, I also happened to stumble upon these online resources:
- Samuel Oloruntoba's explanations of the SOLID principles ;
- Mark Seemann's article on the topic of adapters ;
- Sean G. Wright comment on "Clean architecture - Your approach" ;
- The meetup group of Software Craftsmanship Luxembourg ;
- The meetup group of Tech Excellence.
And you, what architecture do you use for your projects?