Clean Architecture by Robert C. Martin (Uncle Bob): UseCase-centric, strict dependency rule — source code dependencies must point only inward.
Quick Start
State your needs directly, for example: "Help me build a Clean Architecture project skeleton" / "Implement the CreateOrder UseCase for the order module, from entity to controller" / "Check whether the project dependency direction is correct" / "Migrate from a three-layer architecture to Clean Architecture, starting with orders".
When there is insufficient information, I will first provide a reference version, then list the specific information that needs to be supplemented.
Workflow
Step 1: Confirm basic concepts
Ensure the team has a consistent understanding of DDD entities, value objects, and aggregate roots. If unclear, first refer to ddd-architecture-awesome。
Step 2: Define Enterprise Business Rules
Identify aggregate roots → design entities + value objects → implement business rules → define domain events. Refer to 01-core-entities、order-entity example
Step 3: Define UseCase ports
Define an independent Input Port → Output Port → UseCase DTO for each UseCase. Refer to 02-usecase-ports
Step 4: Implement UseCase Interactor
Write the Interactor → orchestrate entities + port calls → publish domain events. Refer to 03-interactors、create-order example
Step 5: Implement the adapter layer
Controller → Presenter → Repository Impl → Gateway Impl → DI configuration. Refer to 04-adapters、05-framework-config
Step 6: Verification and testing
Enterprise unit tests → UseCase integration tests → Adapter integration tests → ArchUnit verification. Refer to 06-dependency-rules、07-testing-strategy
When to Use / When NOT to
| ✅ Applicable | ❌ Not applicable |
|---|---|
| Enterprise-level core systems (orders, payments, inventory) | Temporary scripts, small tools |
| Business rules independent of delivery mechanisms | Simple CRUD with a heavy frontend and light backend |
| Requires strict physical module isolation (15-50 person team) | Team < 5 people, requires rapid iteration |
| Standardized architecture within microservices | A simple three-layer architecture is already sufficient |
| UseCase-driven complex business orchestration | Admin backends without complex business logic |
Boundary
| Category | Capability | Description |
|---|---|---|
| ✅ Good at | Strictly layered enterprise-level systems | 15-50 person team, strong isolation between modules |
| ✅ Good at | UseCase-driven design | Independent Interactor + Port for each use case |
| ✅ Good at | Automated dependency rule checking | ArchUnit fully automated verification of layering compliance |
| ✅ Good at | Multi-language implementation | Can be implemented in Java/Go/TypeScript/C# |
| ⚠️ Requires conditions | Team understands the Interactor pattern | Otherwise the learning cost is high and training is needed |
| ⚠️ Requires conditions | Project has a certain scale | For small projects, Layered/Onion is more suitable |
| ⚠️ Requires conditions | Needs to be paired with a DDD domain model | Using Clean Architecture alone is too abstract |
| ❌ Out of scope | Simple CRUD projects | Use ddd-architecture-layered |
| ❌ Out of scope | Chinese Spring Boot ecosystem | Use ddd-architecture-cola |
| ❌ Out of scope | Need to visualize the ring model | Use ddd-architecture-onion |
| ❌ Out of scope | Need the port adapter concept | Use ddd-architecture-hexagonal |
Audience Description
| User Type | How to Use |
|---|---|
| Backend Architect / Technical Lead | Use directly, select the approach, and implement it according to the Workflow's 6 steps |
| Java Developer | Refer to the code templates in examples/ and implement the UseCase step by step |
| DDD Beginner | First read ddd-architecture-awesome to understand the concepts, then come back to this Skill |
| Multilingual Team (Go/TypeScript/C#) | The architectural rules are universal; refer to the language-agnostic parts in references/ |
Customization: When triggering, specify your tech stack (Java/Go/TS) and module name (e.g., order/payment), and I will generate targeted code templates.
Core Architecture
Enterprise ← UseCase ← Adapter ← Framework
For detailed principles (four-layer structure, architecture comparison, data flow), refer to architecture-principles. For the directory structure, refer to directory-structure。
Development Standards
| Standard | Description | Violation Example |
|---|---|---|
| Entity has zero framework dependencies | Must not import Spring/JPA/Jackson | @Entity appears in core/entity/ |
| Each UseCase has an independent port | One UseCase = one Input Port interface | Multiple UseCases share the same interface |
| Interactor only orchestrates and does not perform business logic | Business if/else must be in the Entity | There is state machine logic in the Interactor |
| Output Port is defined in the UseCase | The Repository interface is defined in the usecase layer | The Adapter defines the Repository interface |
| Data conversion occurs in the Adapter layer | Controller DTO must not cross into the UseCase | @RequestBody DTO is passed directly into the Interactor |
| Transactions are managed in the Framework layer | @Transactional only in adapter/repository | There is @Transactional on an Entity method |
For detailed standards, refer to references/06-dependency-rules.md。
Gotchas
| # | Pitfall | Symptom | Correct Approach |
|---|---|---|---|
| 1 | UseCase contains business logic | There is if/else state judgment in the Interactor | Extract it to Entity/Domain Service |
| 2 | Input Port sharing | Multiple UseCases share one interface | Each UseCase has an independent Input Port |
| 3 | Controller DTO crosses layers | Framework DTO is passed into the UseCase layer | The Adapter layer completes DTO ↔ Domain conversion |
| 4 | There is an @Entity annotation on the Entity | JPA annotations leak into the Enterprise layer | Create a separate JPA Entity in the Adapter layer |
| 5 | Interactor directly calls the Adapter | Skip the Output Port and call the implementation class | Call through the Output Port interface |
| 6 | Output Port is placed in the Adapter layer | UseCase depends on the Adapter package | The Output Port interface is defined in the UseCase layer |
| 7 | UseCase returns an Entity object | Interactor returns Order rather than DTO |
Return a UseCase-specific Output DTO |
| 8 | Over-engineering simple queries | Read operations also go through the full Input→Interactor→Output | Simple queries go directly to the Repository |
| 9 | Adapter contains business logic | if/else in the Controller | All business logic is in the Enterprise layer |
| 10 | Missing ArchUnit checks | Dependency violations cannot be detected automatically | Integrate ArchUnit tests in CI |
| 11 | Mutable domain objects | ValueObject has setter methods | All value objects are immutable (record/final) |
| 12 | Improper UseCase granularity | Interactor is too large (200+ lines) | One Interactor does only one business operation |
| 13 | Ignoring domain events | No event published after key operations | State changes must produce domain events |
| 14 | Transactions in the UseCase layer | @Transactional on the Interactor | Transactions in the Adapter/Repository layer |
| 15 | Entity constructor exposed | Entity uses a public constructor | Use static factory methods (e.g., Order.create()) |
FAQ
| # | Question | Answer |
|---|---|---|
| 1 | What is the difference between Clean Architecture and Hexagonal Architecture? | Clean Architecture is organized around UseCases and emphasizes strict isolation of four layers; Hexagonal uses Port/Adapter as abstraction and emphasizes the symmetry of driving/driven ports. The core goal is the same: inner layers do not depend on outer layers. |
| 2 | When should Interactor vs Domain Service be used? | Interactor orchestrates in the UseCase layer (calls Entity + calls Port); Domain Service encapsulates business rules that span entities in the Enterprise layer (such as PricingService). |
| 3 | Where is business logic written in Service? | Neither. Entities have business methods (pay/cancel), DomainService encapsulates cross-entity rules, and Interactor only orchestrates without making decisions. |
| 4 | Does every UseCase need an independent Input Port? | Yes. This follows the Interface Segregation Principle (ISP). A large interface like IOrderService is an anti-pattern. |
| 5 | What if a UseCase has multiple outputs? | Each output is independently an Output Port. For example, OrderRepository for persistence, EventPublisher for events, and PaymentGateway for payment. |
| 6 | Can the Entity layer reference Repository interfaces? | No. The Enterprise layer must not know of the existence of any Output Port. Repository interfaces are defined in the UseCase layer. |
| 7 | Do simple queries also go through the UseCase layer? | No. Pure read operations can call the Repository directly (queries do not change state). Write operations must go through UseCase. |
| 8 | How should multiple UseCases be organized? | Organize by business aggregate:order/usecase/ place all Order-related CreateOrder/PayOrder/CancelOrder under it. |
| 9 | How are transactions handled in the Interactor? | The Framework layer wraps Interactor calls with declarative transactions (@Transactional). |
| 10 | Should JPA Entity and Domain Entity be separated? | Yes. JPA Entity (@Entity) is in the Adapter layer, Domain Entity (pure POJO) is in the Enterprise layer. Converted via Converter. |
| 11 | How long does it take to migrate a project from a three-layer architecture? | Small (6 weeks) / Medium (12 weeks) / Large (20 weeks). Use the Strangler Fig pattern to migrate gradually by UseCase. |
| 12 | How do you ensure the dependency rules are not violated? | Write ArchUnit tests in the Framework module (see examples/04-archunit-test.md), automatically checked on every commit in CI. |
| 13 | What is the difference between a value object and an entity? | A value object is immutable, has no ID, and is equal by attributes (e.g., Money); an entity is mutable, has a unique ID, and is equal by ID (e.g., Order). |
| 14 | Are domain events published synchronously or asynchronously? | Events are collected synchronously in the Interactor and published to the EventPublisher Port. Asynchronous processing is implemented by the Adapter (writing to a message queue). |
| 15 | Can the adapter layer have multiple implementations? | Yes. One Output Port can have multiple Adapter implementations: JPA/MyBatis/InMemory, switched via Spring Profile. |
Keywords
Clean Architecture, Clean Architecture, Robert C. Martin, Uncle Bob, Enterprise Business Rules, Use Case, Interactor, Input Port, Output Port, Interface Adapter, Dependency Rule, Dependency Inversion, Interface Segregation, DDD, Domain-Driven Design, Layered Architecture, Strict Layering, Use-Case Driven, Domain Model, Entity, Value Object, Aggregate Root, Domain Event, ArchUnit, Dependency Rule Checking
References
Internal
| File | Content |
|---|---|
| references/architecture-principles.md | Four-layer structure, dependency rules, architecture comparison, data flow, directory structure |
| references/01-core-entities.md | Enterprise layer entities, value objects, domain events, exception templates and tests |
| references/02-usecase-ports.md | Input/Output Port definitions, DTO design, port design rules |
| references/03-interactors.md | Interactor implementation templates, complex orchestration, query Interactors, testing |
| references/04-adapters.md | Controller, Repository Impl, Gateway adapter implementations |
| references/05-framework-config.md | Spring DI configuration, Security, Persistence, multiple Profiles |
| references/06-dependency-rules.md | Dependency rule matrix, full ArchUnit test suite, CI integration |
| references/07-testing-strategy.md | Layered testing strategy, Test Doubles, coverage targets |
| references/08-migration-guide.md | Three-layer to Clean Architecture migration guide, Strangler Fig pattern |
| examples/01-order-entity.md | Complete Order entity code + state machine + unit tests |
| examples/02-create-order-usecase.md | Complete CreateOrder UseCase implementation + tests + Test Doubles |
| examples/03-repository-implementation.md | Repository Adapter JPA implementation + integration tests |
| examples/04-archunit-test.md | Complete ArchUnit dependency rule test suite |
| examples/05-domain-event-handling.md | Complete implementation of domain event definition, publishing, and consumption |
| examples/06-monolith-simple.md | Monolith Clean simple version: single-module package-level four layers, directory tree + dependency direction + ArchUnit |
| examples/07-monolith-complex.md | Monolith Clean complex version: multiple aggregates + multiple Interactors, shared kernel + domain isolation |
| examples/08-monolith-multi-module.md | Monolith Clean multi-module version: Maven module-level layering, compile-time enforced dependency direction |
| examples/09-microservice-simple.md | Microservice Clean simple version: package-level four layers + event bus + Kafka adapter |
| examples/10-microservice-complex.md | Microservice Clean complex version: CQRS + Saga + Outbox + multiple subdomains |
| examples/11-microservice-multi-module.md | Microservice Clean multi-module version: 6 modules + API contract independently released |
| examples/12-microservice-complex-multi.md | Microservice Clean complex multi-module: 8 modules + full pattern matrix + subdomain orchestration |
External
- The Clean Architecture — Robert C. Martin (2012)
- Clean Architecture: A Craftsman's Guide — Robert C. Martin (2017)
- Domain-Driven Design: The Blue Book — Eric Evans (2003)
- Get Your Hands Dirty on Clean Architecture — Tom Hombergs
- thombergs/buckpal — Java Reference Implementation
- Hexagonal Architecture — Alistair Cockburn
DDD Skills Ecosystem
| Prerequisite/Follow-up | Skill |
|---|---|
| ← Prerequisite | ddd-architecture-selector — Architecture selection (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-architecture-selector) |
| → Next | ddd-domain-designer — Domain Modeling (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-domain-designer) |
| → Next | ddd-code-reviewer — Code Review (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-code-reviewer) |
| → Next | ddd-architecture-evaluator — Architecture Assessment (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-architecture-evaluator) |
| 🔗 Related | ddd-architecture-hexagonal — Hexagonal Architecture (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-architecture-hexagonal) |
| 🔗 Related | ddd-architecture-layered — Layered Architecture (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-architecture-layered) |
🧭 DDD Skills Journey
📍 You are here:
ddd-architecture-clean— Step 3: Clean Architecture Implementation
awesome(入门) → selector(选型) → clean(整洁架构) + layered/onion/hexagonal/cola → domain-designer/cqrs/api-designer → code-reviewer → testing/devops/evaluator → architecture-doc
**← ddd-architecture-selector | → ddd-domain-designer | 🔗 ddd-api-designer · ddd-testing-strategist | 🏠 ddd-architecture-awesome
(each skill uses npx skills add full-stack-skills/ddd-skills --skill <name> to install)
Security & Stability
- All code templates are for educational purposes. In production, replace placeholder credentials with environment variables.
- Clean Architecture's dependency rule (inward only) naturally prevents domain code from accessing I/O — a built-in security advantage.
- The Interactor pattern ensures each UseCase can be tested independently, without framework or database dependencies.
- Contains no executable scripts. This Skill provides only architectural guidance and code generation patterns.