Clean Architecture Feature Design Framework


1. Clarify the Business Need
Goal: What user problem or business value does this feature address?
Actors: Who interacts with it? (e.g., end-users, external systems)
Success Criteria: How will you measure it? (KPIs, user feedback, metrics)
2. Identify Core Entities
Entities are the business objects and rules that stay the same.
Questions to ask:
What domain concepts are involved?
What invariants or validations belong here?
Output: A list of entity classes/structures with their properties and methods.
3. Define Use Cases (Interactors)
Use Cases orchestrate Entities to fulfill a user goal.
Questions to ask:
Which operations does the feature need? (e.g.,
CreateOrder
,CalculateDiscount
)What data do they require and produce?
Output: Interfaces or abstract classes for each use case, specifying inputs/outputs.
4. Specify Ports (Interfaces)
Inward-facing Ports: interfaces through which controllers invoke use cases.
Outward-facing Ports: interfaces through which use cases call external systems (e.g., repositories, gateways).
Output: Port definitions (e.g.,
OrderRepository
,PaymentGateway
) with method signatures.
5. Sketch Data Flow & Dependencies
- Draw a simple diagram (or list) showing how:
UI → Controller → Use Case → Port → Adapter → External system
Data returns back up the chain.
- Key Principle: Dependencies point inward (outer layers depend on inner abstractions).
6. Implement Adapters
Controllers/Presenters (UI layer): map HTTP/CLI/GUI input to use-case calls, and format responses.
Gateways/Repositories (Infrastructure layer): concrete implementations of ports (e.g., database, REST clients).
Output:
Controller classes
Repository classes
Presenter/Serializer classes
7. Wire It Up
- In your composition root (e.g., application bootstrap):
Instantiate Entities (often not needed explicitly).
Instantiate Repository and Gateway adapters.
Instantiate Use Case implementations, passing adapters into constructors.
Instantiate Controllers, injecting use cases.
8. Write Tests
Unit tests for Entities and Use Cases (mock ports).
Integration tests for adapters (e.g., in-memory DB, sandbox APIs).
Acceptance tests or end-to-end tests covering the full flow.
9. Iterate & Refine
Review SOLID compliance:
Single Responsibility
Open/Closed (add new features by extending, not modifying)
Liskov Substitution
Interface Segregation
Dependency Inversion
Refactor as complexity grows.
10. Document & Communicate
Update architecture diagrams.
Record any new ports, entity rules, or decision rationale.
Share with team for alignment.
Subscribe to my newsletter
Read articles from El Mahdi Hssaine directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
