Critique #1 Distributed Use Cases
In Clean Architecture, Use Cases are first-class citizens, the purpose of an architecture. But what happens when we shift from monolithic to distributed systems? Is the Use Case still unit testable?
Remember the PAINS of thousand-line Application Services?
At first, they all start innocently as small Application Services; it’s just a simple CRUD app!
But then they grow and grow. You spend time scrolling up and down.
You decompose the methods, but you still can’t solve the problem that the Application Services are thousands of lines long!
That’s what attracted me to Uncle Bob’s Clean Architecture. Use Cases were first-class citizens within the architecture.
It was all great… until I had to shift to Distributed Systems, and when I started re-thinking, what exactly are Use Cases?
Given the essential importance of Use Cases in Clean Architecture, we will explore the concept of Use Cases and how Use Cases are translated into System Architecture:
What is the definition of Use Cases in Clean Architecture?
What is the general definition of Use Cases in Software Engineering?
How do we translate Use Cases into Request-Response communication?
How do we implement Use Cases in System Architecture:
Monolithic Architecture
Request Driven Microservice Architecture
Event Driven Microservice Architecture
Are the Use Cases in Clean Architecture consistent with the view of Use Cases within Software Engineering?
In this article, I will argue that the views are NOT consistent; Use Cases are seen from a black-box perspective in Software Engineering, whereas Use Cases are represented from a white-box perspective in Clean Architecture. This difference becomes most apparent as we shift from Monolithic to Microservice Architecture - from centralized to distributed Use Case logic. What about Architecture Testability - in Clean Architecture, Use Case logic is tested solely with Unit Tests, but what happens in Distributed Systems?
Note: The image above is an abstract representation of use case logic. So in the diagram for Microservice Architecture - there are different ways that the Use Case logic is distributed among microservices. We might use an orchestration or choreography approach. The “dotted lines“ above are a symbolic representation. Technical drawings are below.
This article provides a THEORETICAL foundation. Yes, it took me 2000+ words just to cover the concepts.
We will explore the PRACTICAL aspects of implementing Use Cases and transitioning from Monolithic to Microservice Architecture, with CODE SAMPLES in Java and/or C# in some of our upcoming articles. How do we then handle the Testability of the Use Cases?
In this article, the main concept I want to showcase is that the concept of Use Cases in Clean Architecture is “too much” closely tied to centralized systems and unit testability. In distributed systems, we are unable to unit test the full use case behavior (unlike in monolithic systems).
Use Cases in “Screaming Architecture”
What were the origins of Clean Architecture? It started with Uncle Bob formulating Screaming Architecture, referencing Ivar Jacob’s seminal work Object-Oriented Software Engineering: A Use Case Driven Approach.
Uncle Bob writes that Use Cases are the purpose of architecture. Architecture is about intent; it’s about exposing the use cases of an application. Indeed, “good“ architecture is defined as architecture that is centered around use cases: