Key Concepts of the Clean Architecture
1. The Goal of Clean Architecture
- Primary Objective: Create a system that is:
- Independent of frameworks: Frameworks are tools, not the foundation of the architecture.
- Testable: Business rules can be tested without external dependencies.
- Independent of UI: The user interface can change without affecting core business logic.
- Independent of databases: The database is treated as a detail, not a central component.
- Independent of external systems: The system is adaptable to changes in external APIs, tools, or services.
2. The Dependency Rule
- Core Principle: Dependencies must always point inward, toward higher-level policies (business rules).
- Layers in the architecture are organized in a way that the innermost layer (core logic) is independent of external or lower-level details.
3. The Layers of Clean Architecture
The architecture is typically visualized as concentric circles:
- Entities (Innermost Layer):
- These are the core business objects and rules.
- Examples:
Customer
,Order
, orInvoice
classes. - Completely independent of any external systems or frameworks.
- Designed to last for years, even as the system evolves.
- Use Cases (Application-Specific Business Rules):
- Represents the application’s workflows and interactions with entities.
- Implements application-specific logic, such as “Create Order” or “Process Payment.”
- Should not depend on the user interface, database, or external systems.
- Interface Adapters:
- Responsible for translating data between the use cases and external systems (e.g., databases, web interfaces, APIs).
- Examples: Controllers, Presenters, and Gateways.
- Ensures that the core business logic remains unaffected by changes in external systems.
- Frameworks and Drivers (Outermost Layer):
- Contains the implementation details like web frameworks, database access, or external APIs.
- Example: SQL database drivers, HTTP routing, and UI libraries.
- This layer depends on the inner layers, never the other way around.
4. Independence of Frameworks
- Frameworks should not dictate the architecture of the system.
- Treat frameworks as replaceable tools, isolated within the outermost layer.
Example:
- Instead of tightly coupling business logic to a web framework, use controllers in the outer layer that call use case interactors.
5. Independence of UI
- The user interface should be a detail, with no direct influence on the core business rules.
- Changes in UI technologies (e.g., from web to mobile) should not require changes to the core logic.
6. Independence of Databases
- The database should not dictate the structure of the system.
- Use repositories or gateways to abstract database operations.
- This allows the database technology to be changed (e.g., switching from MySQL to MongoDB) without affecting business logic.
7. Independence of External Systems
- External systems, such as payment gateways or messaging services, should be isolated using abstractions.
- Core business logic interacts with these systems through interfaces, ensuring flexibility.
Visualization of Clean Architecture
A typical Clean Architecture diagram looks like this:
[ Entities ] <- Core business rules (innermost layer)
[ Use Cases ] <- Application-specific workflows
[ Interface Adapters ] <- Translate between core and external systems
[ Frameworks/Drivers ] <- Implementation details (outermost layer)
Practical Example: E-Commerce System
Core Business Rules (Entities):
Order
class:javaCopyEdit
public class Order {
private List<Product> products;
public double calculateTotalPrice() {
return products.stream().mapToDouble(Product::getPrice).sum();
}
}
Use Case:
PlaceOrderUseCase
public class PlaceOrderUseCase {
private OrderRepository orderRepository;
public PlaceOrderUseCase(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
public void execute(Order order) {
orderRepository.save(order);
}
}
Interface Adapter:
OrderController
:
@RestController
public class OrderController {
private PlaceOrderUseCase placeOrderUseCase;
public OrderController(PlaceOrderUseCase placeOrderUseCase) {
this.placeOrderUseCase = placeOrderUseCase;
}
@PostMapping("/orders")
public ResponseEntity<String> placeOrder(@RequestBody Order order) {
placeOrderUseCase.execute(order);
return ResponseEntity.ok("Order placed successfully");
}
}
Frameworks/Drivers:
- SQL implementation of
OrderRepository
public class SqlOrderRepository implements OrderRepository {
public void save(Order order) {
// SQL insert query here
}
}
Key Benefits of Clean Architecture
- Testability: Core business logic can be tested without dependencies on frameworks, databases, or UI.
- Flexibility: Changes to frameworks, UI, or databases don’t affect core logic.
- Maintainability: Clear separation of concerns makes the system easier to understand and modify.
- Adaptability: The architecture can evolve with the system’s requirements.
Key Takeaways
- Protect Business Rules:
- Keep the core business logic independent of external systems.
- Organize by Abstraction Levels:
- Structure the system in layers, with dependencies pointing inward.
- Frameworks Are Tools:
- Treat frameworks, databases, and UI technologies as replaceable details.