As we know, the maintenance operation is always more expensive than building the actual software. Whatever we do, the only thing, that never changes, is maintenance cost, isn’t it?
One of the most important things that will affect the cost is to choose software architecture. Based on past my experiences, as a series of two articles, I will try to mention some topics like “what we should consider in order to design a good architecture” and “what clean architecture is“.
Well,
― Robert C. Martin describes a good architecture in the Clean Architecture book as follows;
Good architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy. The ultimate goal is to minimize the lifetime cost of the system and to maximize programmer productivity.
These are our main goals when designing an architecture, right? I think the importance of clean architecture begins with these goals. In my opinion, there are two basic concepts, that we should pay attention, in order to design a good architecture. These are “Coupling” and “Separation of Concerns“.
Let’s recall…
Let’s briefly recall the definition of coupling. Coupling is a measure of the degree of dependence between modules. Modules are either loosely or tightly coupled to each other.
If we want to develop an application with good architecture, we should develop our application/modules as loosely coupled.
In a nutshell, modules should not be “tightly” coupled with each other. They must be easily “extendable” and “replaceable”.
Another important concept is the separation of concerns(SoC). The main goal here is to prevent handling different concerns, in one place. Actually this topic is highly related to the “Single Responsibility” principle.
For example, we might be handling data access operations or UI representation operations in the business logic. After a while, god classes that contain thousands of lines codes, and spaghetti codes come up.
I guess spaghetti is a good thing when we are able to eat it.
Such operations violate SoC. Remember, good architecture should be easily “maintainable”, “less coupled”, and easily “extendable”.
SoC is an important concept especially to be able to design a layered architecture. We should make sure that our modules are loosely coupled and as cohesive as possible, that is, the responsibility relation within a module should be as high and relevant as possible. They shouldn’t deal with different concerns.
I guess the layered architecture has a great place in the life of many software developers. At least for me, it really is.
One of the main principles behind the layered architecture is SoC. The goal is to prevent the database, domain or UI codes from getting mixed up and to separate their responsibilities.
Layered architecture usually comes in a form like the one above. The dependency flow here is from the presentation to the data access layer. In fact, although we try to provide SoC and loosely coupling, there is a hierarchy/dependency between layers.
One of the main principles behind clean architecture is Dependency Inversion principle. With this principle, it is possible to make components in our architecture more decoupled from each other and abstracted from certain technologies.
Let’s look at the picture from this point of view.
The concept that Uncle Bob calls “Clean Architecture” or the design that Alistair Cockburn calls “Hexagonal Architecture” is as above. It is a domain-centric design on which dependency inversion is applied.
Instead of a hierarchical flow from top to bottom, it places the application domain, which contains business logic and domain models, in the middle of the architecture as the core. It also reverses the dependencies of all modules. Dependencies always point inwards (core layer). We can think of it as a plug-in-based structure. Plug it, out.
This approach gives us the ability to easily extend, test and replace any part as we wish.
Can you imagine we are trying to replace the scissors with a knife?
We usually expect a well designed architecture to cover the following concerns.
If we look at the above picture again, we can see it how it is more easy to replace the scissors with the knife without affecting the other tools.
Well, now let’s look at the details of the clean architecture concept.
First, the Hexagonal architecture that we have seen below is an applied instance of clean architecture concept.
The “Application Domain” is the innermost core layer. The heart of the architecture. It doesn’t have any dependencies. It is located in the middle of the architecture and is isolated from other frameworks, databases, UI, etc. It mainly contains domain entities, use-cases and external interfaces.
There are also “input” and “output” ports around it. Implementations which are around it are called “adapter”. These adaptors implement ports.
For example, if we look at the above project structure, there is a “MovieService” class under the “Services” folder. Well, what responsibilities are this service performing? Do you think is it clear enough?
Now let’s look at these services which are applying the single responsible use-case approach.
Under the “MovieUseCases” folder, there are “CreateMovieHandler” and “GetBestMoviesForKidsHandler” use-cases. Now their responsibilities are much more clear, right? God classes vs single responsible classes.
Let’s take a look at the above picture again. We can see ports are interfaces that are defined in the domain layer in order to invert dependency.
The ones around are implementations of ports, called adapters. It can be a SQL Server in the “Infrastructure” part or a NoSQL implementation. It can be a Web UI in the “Presentation” part or a REST API.
As we can see the core domain layer locates the middle of the architecture completely as isolated and decoupled from the other modules and technologies. The whole dependency flow points to inward.
At this point, I have tried to explain the “why clean architecture” topic and I tried to mention the general concept of it. I know this article a bit abstract, that the reason is in the next part of this article, I will mention about the implementation of clean architecture in .NET Core.
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
https://pusher.com/tutorials/clean-architecture-introduction
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles?WT.mc_id=DT-MVP-5003382
https://www.freecodecamp.org/news/a-quick-introduction-to-clean-architecture-990c014448d2/
https://slides.com/gokgokalp/aspnet-core-clean-architecture#/
{:tr} Makalenin ilk bölümünde, Software Supply Chain güvenliğinin öneminden ve containerized uygulamaların güvenlik risklerini azaltabilmek…
{:tr}Bildiğimiz gibi modern yazılım geliştirme ortamında containerization'ın benimsenmesi, uygulamaların oluşturulma ve dağıtılma şekillerini oldukça değiştirdi.…
{:tr}Bildiğimiz gibi bir ürün geliştirirken olabildiğince farklı cloud çözümlerinden faydalanmak, harcanacak zaman ve karmaşıklığın yanı…
{:tr}Bazen bazı senaryolar vardır karmaşıklığını veya eksi yanlarını bildiğimiz halde implemente etmekten kaçamadığımız veya implemente…
{:tr}Bildiğimiz gibi microservice architecture'ına adapte olmanın bir çok artı noktası olduğu gibi, maalesef getirdiği bazı…
{:tr}Bir önceki makale serisinde Dapr projesinden ve faydalarından bahsedip, local ortamda self-hosted mode olarak .NET…
View Comments
Harika bir yazı olmuş. Uzun zamandır bu konuda bilgi ihtiyacı olan bir kişi olarak yazının tamamını bir solukta su içer gibi okudum. En sonunda en heyecanlı kısmında bitti :( Bir sonraki yazıyı sabırsızlıkla bekliyorum elinize sağlık. Ayrıca böyle bir konuda Türkçe kaynak kazandırdığınız için ayrıca tebrik ederim.
Çok teşekkür ederim güzel yorumunuz için. Şuan 2. kısmını yazmaktayım. :)
Türkçe kaynak bu konuda sıkıntılıydı, uzun zamandır yeni başlayacağımız bir proje için bu mimariyi inceliyorum. Sizin anlatımınızla bakmak da bloğunuzu takip eden ben açısından güzel oldu. Github'da Steve Smith'e sorduğum soruyu size de sormak isterim. Bu mimari db bağımsız diyoruz, okuyoruz ancak gerçek bir kullanım veya örneği yok. Yani hem redis, hem mssql hem de mongo kullanacaksak ne yapacağız? Teoride bir çok şey yerine oturmasına rağmen, pratikte herşeyi ayırmak adına birbirinin aynısı olmayan ancak birbirine aşırı benzer kodlar çıkmıyor mu?
Merhaba, öncelikle güzel yorumunuz için teşekkür ederim. Evet, eğer farklı ihtiyaçlar karşısında farklı service'ler kullanacaksak, onları da bir bir implemente etmek gerekiyor. En azından ben öyle yapıyorum. Dediğiniz gibi benzer kodlar/kod tekrarları ortaya çıkabiliyor, oradaki o ince ayrımı iyi yapmak gerekiyor bence. Hiç kod tekrarına düşmemek adına abstract yapa yapa bu seferde mimariyi over engineering yoluna doğru da itebiliyoruz açıkcası. Yer yer bu tradeoff'u seçmek gerekiyor sanırım. Independency vs Reusability? Kesin bir cevabı yok bence. :) Sizce?
Thank you very much for the nice and clean article. It's a good entrance to a very important subject, "clean architecture". We're waiting for the next part of this series. Don't make us wait too long :)
Thanks mate :) I'm working on it. :)
Thanks for sharing
Çok yararlı bir kaynak kazandırmışsınız, tek solukta okudum. Çok teşekkürler. İkincisini beklemedeyim.
Çok teşekkür ederim değerli yorumunuz için.
Paylaşım için teşekkürler, 2. makaleyi okumadan önce bunu yeniden okumak iyi oldu.
Emeğine sağlık
Ben teşekkür ederim. :)