[TIL-5] The Clean Architecture

In previous article I’ve written the story about SOLID Principle that introduced by Robert C. Martin (uncle bob). The clean architecture is also a terminology that popularized by Robert C. Martin (uncle bob).

In his book “Clean Architecture: A Craftsman’s Guide to Software Structure and Design” famous writer Robert C. Martin (uncle bob) gives an engineering some significant focuses like testability and independence of frameworks, databases and interfaces.

Based on his article at blog.cleancoder.com, The Clean Architecture has these constraints,

  1. Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
  2. Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
  3. Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
  4. Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
  5. Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.

From Uncle Bob’s Architecture we can partition our code in 4 layers.


Entities encapsulate Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter so long as the entities could be used by many different applications in the enterprise.

  • Address your domain object
  • Apply only logic that is applicable in general to the whole entity (e.g., validating the format of a hostname)
  • Plain objects: no frameworks, no annotations

Use Case Layer

The software in this layer contains application specific business rules. It encapsulates and implements all of the use cases of the system

  • Represent your business actions: it’s what you can do with the application. Expect one use case for each business action
  • Pure business logic, plain code (except maybe some utils libraries)
  • The use case doesn’t know who triggered it and how the results are going to be presented (for example, could be on a web page, or — returned as JSON, or simply logged, and so on.)
  • Throws business exceptions


The software in this layer is a set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web

  • Retrieve and store data from and to a number of sources (database, network devices, file system, 3rd parties, and so on.)
  • Define interfaces for the data that they need in order to apply some logic. One or more data providers will implement the interface, but the use case doesn’t know where the data is coming from
  • Implement the interfaces defined by the use case
  • There are ways to interact with the application, and typically involve a delivery mechanism (for example, REST APIs, scheduled jobs, GUI, other systems)
  • Trigger a use case and convert the result to the appropriate format for the delivery mechanism
  • the controller for a MVC

Frameworks and Drivers layer

According to Uncle Bob:

The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc.This layer is where all the details go.

  • Use whatever framework is most appropriate (they are going to be isolated here anyway)

For example of the clean architecture, I’d like to use example from mattia-battiston in his github repository that called clean-architecture-example

Real example


The center of your application is not the database. Nor is it one or more of the frameworks you may be using. The center of your application is the use cases of your application — Unclebob (source)

Clean architecture helps us to address, or at least mitigate, these basic issues with architecture design:

  • Decisions are taken too soon, frequently toward the start of a project, when we know the least about the problem that we have to solve.
  • It’s difficult to change, so when we find new necessities we need to choose if we need to hack them in or go through an expensive and painful re-design. We as a whole know which one generally wins. The best architectures are the ones that allow us to defer commitment to a particular solution and let us change our mind
  • It’s centered around frameworks. Frameworks are tools to be utilized, not architectures to be conformed to. Frameworks frequently require commitments from you, however they don’t commit on you. They can develop in various ways, and afterward you’ll be stuck keeping their standards and idiosyncrasies
  • It’s centered around the database. We frequently consider the database first, and afterward make a CRUD framework around it. We end up utilizing the database objects all over and treat everything in terms of tables, rows and columns
  • We center around technical aspects and when asked about our architecture, we make statements like “it’s servlets running in tomcat with a oracle db utilizing spring”
  • It’s elusive things which rolls out each improvement longer and more agonizing
  • Business logic is spread all over the place, dispersed across numerous layers, so when checking how something works our only option is to investigate the entire codebase. Far and away more terrible, frequently it’s copied in various spots
  • Encourages slow, weighty tests. Regularly our only choice for tests is to go through the GUI, either because the GUI has a ton of logic, or because that the architecture doesn’t permit us to do otherwise. This makes tests delayed to run, heavy and brittle. It brings about individuals not running them and the build behind broken often
  • Infrequent deploys because it’s difficult to make changes without breaking existing functionalities. Individuals resort to long-lived feature branches that only get integrated at the end and result in enormous deliveries, instead of small incremental ones







The Joy of discovery is one of the best things about being a software developer ~ Eric Elliott