DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Build a Full Stack App With SvelteKit and OceanBase
  • What Is API-First?
  • Application Mapping: 5 Key Benefits for Software Projects
  • Projections/DTOs in Spring Data R2DBC

Trending

  • Implementing Explainable AI in CRM Using Stream Processing
  • Useful System Table Queries in Relational Databases
  • Introducing Graph Concepts in Java With Eclipse JNoSQL, Part 2: Understanding Neo4j
  • Monoliths, REST, and Spring Boot Sidecars: A Real Modernization Playbook
  1. DZone
  2. Data Engineering
  3. Databases
  4. Clean Architecture Is Screaming

Clean Architecture Is Screaming

Uncle Bob's Clean Architecture keeps your application flexible, testable, and highlights its use cases. But there is a cost: No idiomatic framework usage!

By 
Grzegorz Ziemoński user avatar
Grzegorz Ziemoński
·
Mar. 07, 17 · Tutorial
Likes (26)
Comment
Save
Tweet
Share
55.4K Views

Join the DZone community and get the full member experience.

Join For Free

Welcome to the fifth installment of little architecture series! So far we have covered layers, hexagons, onions, and features. Today, we’ll look at a close friend of all four – Uncle Bob’s Clean Architecture, initially introduced here.

What Is Clean Architecture?

Clean Architecture builds upon the previously introduced four concepts and aligns the project with best practices like the Dependency Inversion Principle or Use Cases. It also aims for a maximum independence of any frameworks or tools that might stay in the way of application’s testability or their replacement.

Clean Architecture divides our system into four layers, usually represented by circles:

  • Entities, which contain enterprise-wide business rules. You can think of them as about Domain Entities a la DDD.
  • Use cases, which contain application-specific business rules. These would be counterparts to Application Services with the caveat that each class should focus on one particular Use Case.
  • Interface adapters, which contain adapters to peripheral technologies. Here, you can expect MVC, Gateway implementations and the like.
  • Frameworks and drivers, which contain tools like databases or framework. By default, you don’t code too much in this layer, but it’s important to clearly state the place and priority that those tools have in your architecture.

Between the circles, there is a strong dependency rule – no code in the inner circle can directly reference a piece of code from the outer circle. All outward communication should happen via interfaces. It’s exactly the same dependency rule as we introduced in the Onion Architecture post.

Apart from the layers, Clean Architecture gives us some tips about the classes we need to implement. As you can see in the picture below, the flow of control from the Controller to the Use Case goes through an Input Port interface and flows to the Presenter through an Output Port interface. This ensures that the Use Case and the user interface are properly decoupled. We’ll see an example of this later in the implementation section.

The Essence of Clean Architecture

I see two things that make Clean Architecture distinct and potentially more effective than other architectural styles: strong adherence to the Dependency Inversion Principle and Use Case orientation.

Strong Adherence to DIP

Similarly to its Onion cousin, Clean Architecture introduces the Dependency Inversion Principle at the architectural level. This way, it explicitly states the priorities between different kinds of objects in your system. In a way, Clean Architecture does a better job at this, as it leaves no doubt about the tools like frameworks or databases – they have a dedicated layer outside all others.

Use Case Orientation

Similarly to what we’ve seen in Package by Feature, Clean Architecture promotes vertical slicing of the code and leaving the layers mostly at the class level. The major difference between the two is that instead of focusing on a blurry concept of a feature, it reorients the packaging towards Use Cases. This is important as, ultimately, in any application that has some sort of GUI, one could identify real Use Cases. It’s also important to note that entities sit in a different layer as in complex systems, one Use Case can orchestrate several entities to cooperate and categorizing it by the type of the entity would be artificial.

Implementing Clean Architecture

We can’t be 100% sure about how Uncle Bob would implement a Clean Architecture today, as his book about it comes out in July (I preordered it already and will do a review or rehash of this post then), but we can look at the GitHub repository of his Clean Code Case study:

Packaging

As you can see, the Entities and Use Cases layers have their own separate packages, while the other layers can be identified only conceptually. The socketserver,  http, and  view packages can be considered a part of the Frameworks and Drivers, while gateways package is a little bit ambiguous – their implementation is surely the Interface Adapters layer, but their interfaces conceptually belong to Use Cases. My guess is that the interfaces are extracted to a separate package so they can be shared between different Use Cases. But it’s just a guess!

By looking at the usecases.codecastSummeries, we can get more insight into how a complete Use Case package looks like. As you can see, it accommodates all classes related to the execution of a particular Use Case: the view, controller, presenter, boundaries, view and response models, and the Use Case class itself.  This might be a lot more classes than you usually see in your projects when you execute an Application Service, but that’s what it takes to go perfectly Clean.

Internals

If you dug deeper into the implementation of the project’s classes, you’d see no annotation there other than @Override. That’s because of the frameworks being at the very outer layer of the architecture – the code is not allowed to reference them directly. You might ask, how could I leverage Spring in such a project? Well, if you really wanted to, you’d have to do some XML configurations or do it using @Configuration and @Bean classes. No @Service, no @Autowired, sorry!

My Extra Advice

Pulling off a Clean Architecture might be a demanding task, especially if you worked with a Package by Layer, fat controllers kind of project before. And even if you get the idea and necessary skills to implement it, your colleagues might not. They might want to do this anyway, but simply forget to add interfaces or work around framework annotations when necessary. One way to prevent some of these issues could be to create a Maven module for each of the layers so that breaking a rule won’t even compile. At the same time, if you don’t have these already, introducing Pair Programming or Code Reviews will help you to prevent people from messing up with the dependency declarations (circular dependencies would not work, but adding Spring both to the Use Cases and Adapters module would!).

Benefits of a Clean Architecture

  • Screaming – Use Cases are clearly visible in the project’s structure
  • Flexible – you should be able to switch frameworks, databases or application servers like pairs of gloves
  • Testable – all the interfaces around let you setup the test scope and outside interactions in any way you want
  • Could play well with best practices like DDD – to be honest, I haven’t seen it so far, but I also don’t see anything stopping you from making an effective mix of DDD’s Strategic and Tactical Patterns with Clean Architecture

Drawbacks of Clean Architecture

  • No Idiomatic Framework Usage – the dependency rule is relentless in this area
  • Learning Curve – it’s harder to grasp than the other styles, especially considering the point above
  • Indirect – there will be a lot more interfaces than one might expect (I don’t see it as necessarily bad, but I’ve seen people pointing this out)
  • Heavy – in the sense that you might end up with a lot more classes than you currently have in your projects (again, the extra classes are not necessarily bad)

When to Use Clean Architecture

Before I say something, let me note that I haven’t tried implementing it in a professional context yet, so all of it is a gut feeling. We will probably get some more knowledgeable advice from Uncle Bob himself in his upcoming book.

If we consider Clean Architecture‘s biggest drawbacks and its essence, I would derive the following criteria to consider:

  • Is the team skilled and/or convinced enough? One might consider this lame, but if people just don’t get it or they don’t want to do this, imposing the rigor of Clean Architecture on them might be counter-productive.
  • Will the system outlive major framework releases? Since we’re talking about heavy technology flexibility here, it’s important to consider if we’ll ever capitalize on this benefit. My experience so far suggests that most systems will, even if the developers won’t be in the company by then.
  • Will the system outlive the developers and stakeholders employment? Since Clean Architecture is so sound and makes Use Cases so clearly visible, systems that follow its principles will be much simpler to comprehend in the code, even if those who wrote it and asked for it are already gone.

Summary

Clean Architecture looks like a very carefully thought and effective architecture. It makes the big leap of recognizing the mismatch between Use Cases and Entities and puts the former in the driving seat of our system. It also gives a clear place for Frameworks and Drivers in our system – a separate layer outside all other layers. This, combined with the dependency rule might give us a plethora of benefits, but also might be way harder to pull off. In the end, it boils down to the question whether the system will live long enough so that the investment returns.

Architecture Use case Database Dependency inversion principle Interface (computing) Framework Dependency application

Published at DZone with permission of Grzegorz Ziemoński, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Build a Full Stack App With SvelteKit and OceanBase
  • What Is API-First?
  • Application Mapping: 5 Key Benefits for Software Projects
  • Projections/DTOs in Spring Data R2DBC

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!