Software Architecture — Make it clean

R.R. Dev
6 min readNov 30, 2023

--

Sometime we don’t like the idea of looking for a deeply answer for our problems, as developers, some times we got a solution that works but that solution came with a lot of bad practices and tweaking the changes maybe made our job more much difficult, so, I understand the feeling of leave it as it is and don’t worry about it, it’s a problem for tomorrow haha, but let me tell you something, it’s necessarily and let me explain you why and how can we improve code quality and good practices.

Why?

If you’re asking this I’m guessing you’re pretty new coding, so, let me tell you a story about my hell in a one project I got involved long time ago. There was a feature, establish a connection between 2 machines, our server and clients computer, it needs to be remote and be intelligent enough to close it when it’s needed but keep it if it was needed, the architecture from a big picture was pretty simple, 2 machines connected through a web socket on Kubernetes pods that will automatically die if we needed, easy, well, not that easy. First time I saw the code I got terrified, classes with hundreds of lines, methods that were doing multiple things, bad naming, I couldn’t understand how the code was working, even my coworker didn’t know how to explain me what the heck was going on and he wrote it, adding a single line of code could bring hell to our door, it took me 2 weeks to understand how everything was and 1 more week making the changes, that was precious time that we won’t get it back, deploy the changes for our costumers ran a little late just because we couldn’t read our own code, and that it’s a problem.

I just mentioned the readability problem, but there was others, for example, duplicate code, performance issues, data type concerns, and a lot more, so, develop with high quality code it’s something we all need to learn and I’ll show you the knowledge I’ve been learning through the years so, let’s get started!

Layers

Well, before we go to a deeply explanation about architecture, we want to understand the the based of this, and we call them layers but, what exactly are layers? Excellent question, layers are the different levels or portions of an application that represent different levels of abstraction, and their characteristics are:

  • Single responsibility
  • Isolate roles and skills
  • Multiple implementations
  • Varying rates of change

So, I think you can see why it’s important to have the right number of layers in our system architecture right? What is easier to understand and maintain, a big application with a single layer or a big application with multiple layers? or in other words, what is easier, looking for a book in a library with one single shelf or in a library with multiple shelf with a category description? Do you see it now? I’m pretty sure you’re ready for the next section.

Domain Centric Architecture

Maybe you heard this before, domain centric architecture is what the name is saying, a model where we are focusing on the domain layer, I know it’s pretty common having a database centric architecture and focus everything from the database and I know database and domain are closely related, but, let me tell you something

Small changes could bring big impacts. I’m not saying the common three level architecture won’t work, it could, but think about it in that way, a small change, setting earth as the center of the solar system it’s a small change, but the impact could be catastrophic, sun couldn’t be the same so it will have a tremendous impact on life in earth, the translation cycles couldn’t be the same, and we can keep talking about all the impacts for days but I think you got the point

Database centric model vs domain centric model

Now, let’s see the models, the first one (from left to right) it’s a database centric model, and all the layers are depending on the database, if you can’t see the pros and const having the other model at the right let me tell you this. With the first model, you basically have all the business logic in one layer, that means, more code and responsibilities in a single layer, if the system got bigger then your labyrinth too, on the other hand, we can distribute responsibilities in a fairer way ending in a more readable and clear code, database it’s just a detail you can use to store data, presentation (UI) has a dependency with the Application layer (We will talk about this layer later) as well as the architecture, and application has the dependency on domain, now, you can have multiple and distributed logic in each of the layers having a more understandable, maintainable and testable code, now, let’s moving to the next layer.

Application Layer

We can translate this as the layer for implement the use cases, but, what does this mean? We currently have a business logic layer in the previous model so, what’s different? Great question, here, the different it’s the level of abstraction, the application layer just organized everything to make the use case work but it doesn’t mean it does everything, for example, if you want to get all the product that match your query the application layer will ask to the database for the data, but not running the search, that’s job of another layer, maybe you got the data from database, but still need to return a calculated value from that domain data, well, let the domain takes the responsability and just invoke a method, see? The app layer can set everything to get the job done but here the application layer doesn’t has all the responsibility for every process, now we have a clearer layer for our business logic.

Command and Query Responsibility Segregation

Before started let’s show the difference between command and query to understand better what I want to explain

We say command to every action that modify the state of the system but it’s not returning a value

We say query to every action that not modify the state of the system but it’s return a value

With this said, I know you’re thinking, well, I can try it but it’s not always possible, and you’re right, some times we need to do a mix of them because it’s not possible doing it in another way, for example, if you implement a create operation on the database, maybe you are using a library or you need to implement a create method that returns the id of the object you’re adding to your database, so, yeah, I get it, but you should need to try keeping the difference all you can so can avoid collateral damages when your coding like waste of memory, mix pointers or data corruption, it will be always preferable having this two terms separately.

There are three types of models for this command query segregation or CQRS, are you ready?

Single Database CQRS

This is the simplest model for CQRS, it’s basically what the name says, you have one and just database for reading and writing, for commands and queries.

Two Database CQRS

As you could think, the next model has two databases, one for reading operations and optimized for reading operation, and other one for writing operations and optimized for writing operations, the way you update the data in the reading database is up to you.

Event Sourcing CQRS

The more complex model of the three, you basically don’t save the current state of the entities, what you do instead it’s store the states modification over time so keep a history that you can reconstruct if you needed.

Enough of models

I know you’re tired of theory and diagrams and models, so, I’ll leave it as it is right now and I’ll continue in a later post because there are another subjects you need to learn and they’re more complex or has their own world to be explain, next time, we’ll be talking about Micro-Services, for now, I hope you enjoyed reading this post and… See you later!

--

--