There are projects that developers have nicknamed “Frankenstein” or “a monster”. These nicknames are applied to software applications that are hard to maintain, have grown well beyond their initial scope, may be riddled with code smells, and are usually at the point where it would be too costly to build necessary functionality into it.
While an application rewrite sounds like the answer, there are other costs associated with that as well. The developers and the business run into frustration because the overgrown app hinders the growth of the business and fails to meet the business needs. In this post, we will look at how you can set up your application with a better understanding of software architecture and the importance of Clean Architecture.
The Purpose of Software Architecture
A failure of software architecture is thinking that the sole goal of software architecture is to make a properly working system. However, there are more goals to software architecture. Software architects also have to consider things such as development, deployment, and maintenance. They must have a holistic view of the system with the following questions in mind:
- Who will be building this system? Who will be maintaining this system?
- How will this system be deployed?
- Does this system have a sturdy enough foundation to support current needs and allow for growth with business needs?
Software architects have to establish a foundation that can be managed well on the development side while also minimize costs and frustrations for other stakeholders.
The architecture of the system should show use cases, features, and behaviors in a way that is intuitively perceived by developers. This should make it easy for them to understand what they need to achieve and how to organize their code in a way that makes it easy to deploy to the desired environment(s) and easy to maintain.
What is Clean Architecture?
Clean Architecture is an architectural approach that acknowledges the similarities in other approaches to software architecture, including:
- Hexagonal Architecture - Ports & Adapters from Alistair Cockburn
- Onion Architecture - from Jeffrey Palermo
- Data, Context, and Interaction (DCI) from James Coplien and Trygve Reenskaug
- Boundary Control Entity (BCE) from Ivar Jacobsend
The key to these architectural approaches is separation of concerns. There are layers for use cases, business rules, and other key concepts. Each of those layers - except the business rules - has a dependency on an inner layer. These dependencies are unidirectional.
Clean Architecture is an attempt at aggregating these architectures in one idea.
Characteristics of Clean Architecture
Systems that follow these approaches have the following characteristics:
- Testability - Business rules should be testable without having to invoke the UI, database, or other external servers.
- Independence - With the separation of concerns, there are key layers that can exist independently:
- UI - When architected cleanly, the business logic can be shared by multiple UI types including web, desktop, mobile, and command-line interfaces.
- Database - The business rules are not bound to a database platform, vendor, or type. Whether you choose relational data or NoSQL data, that decision should not impact the business rules.
- External services - The business rules should not rely on external services.
If this is hard to think about generally speaking, consider these questions:
Does your marketing department change their messaging whether the data is stored in SQL Server versus Azure Cosmos DB?
Do your accounting processes follow different calculation rules if they are handled on a website versus a mobile app?
Does your paid time off policy differ whether your email notifications are sent by your on-premises mail server versus a mail service in the cloud?
The key thing here is that your business rules are independent of the technical implementation decisions.
Clean Architecture in Diagrams
When Clean Architecture was presented to the community, we were presented a diagram of concentric circles as well as a flowchart, as presented in the Clean Coder blog.
Source: Clean Coder Blog
There is a lot going on in this diagram. For this post, we want a high level look at Clean Architecture, so we’re going to talk about the layers and how they interact.
In this diagram, there are 4 concentric circles that show things from the innermost general to the outermost specific implementations. Let’s look at them going from inside to the outermost ring.
Entities are the innermost circle. This is where the enterprise business rules belong. This is the central business logic that everything depends on. As this is the center of the concentric circles, this can be seen as the Core of the application.
The next layer out is for use cases. This is where application-specific rules belong. Application-specific logic still relies on the heart of the enterprise business rules. However, application-specific logic is still within the focus of the domain and not tied into technical decisions such as UI or database.
Controllers, Gateways, & Presenters
The third layer from the inside of the Clean Architecture concentric circles is labeled for controllers, gateways, and presenters. This is where the interface adapters live. At this level, the interface adapters can depend on the application-specific logic. However, it will not refer directly to the enterprise business logic. The interface adapters do not know about the technical decisions made outside of them. They do not know about the UI or database.
Frameworks & Drivers
The outermost circle of the Clean Architecture concentric circles is for frameworks and drivers. This is the layer where the technical decisions become apparent. This is where you put logic related to the UI and database. These tools fulfill their roles in implementing the logic via the interface adapters.
Why Clean Architecture?
Clean Architecture enables you as a software architect to establish a solid foundation for your system. It allows you to create UIs and APIs without changing the business logic. You can provision your infrastructure separately from implementing business logic. You can separate parts of the system in a way that makes it easier to grow and maintain. It also becomes easier to see what needs to be deployed and eases deployment woes.
Our Webinar on Getting Started in C#
While this sounds like it can be complex to get started, there are templates out there for getting started with a solid base. We have a webinar to help you get started with an opinionated Clean Architecture template that has elements from domain-driven development weaved in with other Clean Architecture layers. Check our events for upcoming webinars!
If you want to learn how to incorporate Clean Architecture in an existing code base, contact us today!
If you are interested in learning about Clean Architecture in languages other than C#, check out these other blogs: