Skills · Coding

Architecture Patterns

Unverified31/40

Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use this skill when designing clean architecture for a new microservice, when refactoring a monolith to use bounded contexts, when implementing hexagonal or onion architecture patterns, or when debugging dependency cycles between application layers.

Originally by wshobson · MIT

Claude CodePartialHas SKILL.md but declares no allowed-tools — Claude Code will ask for permission each time
CursorPartialPlain prose you can paste in — but no Cursor rules file
CodexPartialPlain prose you can paste in — but no AGENTS.md
Gemini CLIPartialPlain prose you can paste in
CopilotPartialPlain prose you can paste in — but no Copilot instructions file
npx agentalley add architecture-patterns

This command does not work yet — the CLI is still being built. Until then, use Raw in the reader below to take the file.

Who is stuck, and on what

Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use this skill when designing clean architecture for a new microservice, when refactoring a monolith to use bounded contexts, when implementing hexagonal or onion architecture patterns, or when debugging dependency cycles between application layers.

The whole source

No sign-in, no blur, nothing truncated
architecture-patterns/SKILL.md165 lines7.8 KBRawView on GitHub
Frontmatter — 2 properties
namearchitecture-patterns
descriptionImplement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use this skill when designing clean architecture for a new microservice, when refactoring a monolith to use bounded contexts, when implementing hexagonal or onion architecture patterns, or when debugging dependency cycles between application layers.
1---
2name: architecture-patterns
3description: Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use this skill when designing clean architecture for a new microservice, when refactoring a monolith to use bounded contexts, when implementing hexagonal or onion architecture patterns, or when debugging dependency cycles between application layers.
4---A5No allowed-tools declared — no way to tell what this skill may touch
5 
6# Architecture Patterns
7 
8Master proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design to build maintainable, testable, and scalable systems.
9 
10**Given:** a service boundary or module to architect.
11**Produces:** layered structure with clear dependency rules, interface definitions, and test boundaries.
12 
13## When to Use This Skill
14 
15- Designing new backend services or microservices from scratch
16- Refactoring monolithic applications where business logic is entangled with ORM models or HTTP concerns
17- Establishing bounded contexts before splitting a system into services
18- Debugging dependency cycles where infrastructure code bleeds into the domain layer
19- Creating testable codebases where use-case tests do not require a running database
20- Implementing domain-driven design tactical patterns (aggregates, value objects, domain events)
21 
22## Core Concepts
23 
24### 1. Clean Architecture (Uncle Bob)
25 
26**Layers (dependency flows inward):**
27 
28- **Entities**: Core business models, no framework imports
29- **Use Cases**: Application business rules, orchestrate entities
30- **Interface Adapters**: Controllers, presenters, gateways — translate between use cases and external formats
31- **Frameworks & Drivers**: UI, database, external services — all at the outermost ring
32 
33**Key Principles:**
34 
35- Dependencies point inward only; inner layers know nothing about outer layers
36- Business logic is independent of frameworks, databases, and delivery mechanisms
37- Every layer boundary is crossed via an abstract interface
38- Testable without UI, database, or external services
39 
40### 2. Hexagonal Architecture (Ports and Adapters)
41 
42**Components:**
43 
44- **Domain Core**: Business logic lives here, framework-free
45- **Ports**: Abstract interfaces that define how the core interacts with the outside world (driving and driven)
46- **Adapters**: Concrete implementations of ports (PostgreSQL adapter, Stripe adapter, REST adapter)
47 
48**Benefits:**
49 
50- Swap implementations without touching the core (e.g., replace PostgreSQL with DynamoDB)
51- Use in-memory adapters in tests — no Docker required
52- Technology decisions deferred to the edges
53 
54### 3. Domain-Driven Design (DDD)
55 
56**Strategic Patterns:**
57 
58- **Bounded Contexts**: Isolate a coherent model for one subdomain; avoid sharing a single model across the whole system
59- **Context Mapping**: Define how contexts relate (Anti-Corruption Layer, Shared Kernel, Open Host Service)
60- **Ubiquitous Language**: Every term in code matches the term used by domain experts
61 
62**Tactical Patterns:**
63 
64- **Entities**: Objects with stable identity that change over time
65- **Value Objects**: Immutable objects identified by their attributes (Email, Money, Address)
66- **Aggregates**: Consistency boundaries; only the root is accessible from outside
67- **Repositories**: Persist and reconstitute aggregates; abstract over the storage mechanism
68- **Domain Events**: Capture things that happened inside the domain; used for cross-aggregate coordination
69 
70## Detailed patterns and worked examples
71 
72Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient.
73 
74## Testing — In-Memory Adapters
75 
76The hallmark of correctly applied Clean Architecture is that every use case can be exercised in a plain unit test with no real database, no Docker, and no network:
77 
78```python
79# tests/unit/test_create_user.py
80import asyncio
81from typing import Dict, Optional
82from domain.entities.user import User
83from domain.interfaces.user_repository import IUserRepository
84from use_cases.create_user import CreateUserUseCase, CreateUserRequest
85 
86 
87class InMemoryUserRepository(IUserRepository):
88 def __init__(self):
89 self._store: Dict[str, User] = {}
90 
91 async def find_by_id(self, user_id: str) -> Optional[User]:
92 return self._store.get(user_id)
93 
94 async def find_by_email(self, email: str) -> Optional[User]:
95 return next((u for u in self._store.values() if u.email == email), None)
96 
97 async def save(self, user: User) -> User:
98 self._store[user.id] = user
99 return user
100 
101 async def delete(self, user_id: str) -> bool:
102 return self._store.pop(user_id, None) is not None
103 
104 
105async def test_create_user_succeeds():
106 repo = InMemoryUserRepository()
107 use_case = CreateUserUseCase(user_repository=repo)
108 
109 response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))
110 
111 assert response.success
112 assert response.user.email == "[email protected]"
113 assert response.user.id is not None
114 
115 
116async def test_duplicate_email_rejected():
117 repo = InMemoryUserRepository()
118 use_case = CreateUserUseCase(user_repository=repo)
119 
120 await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))
121 response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice2"))
122 
123 assert not response.success
124 assert "already exists" in response.error
125```
126 
127## Troubleshooting
128 
129### Use case tests require a running database
130 
131Business logic has leaked into the infrastructure layer. Move all database calls behind an `IRepository` interface and inject an in-memory implementation in tests (see Testing section above). The use case constructor must accept the abstract port, not the concrete class.
132 
133### Circular imports between layers
134 
135A common symptom is `ImportError: cannot import name X` between `use_cases` and `adapters`. This happens when a use case imports a concrete adapter class instead of the abstract port. Enforce the rule: `use_cases/` imports only from `domain/` (entities and interfaces). It must never import from `adapters/` or `infrastructure/`.
136 
137### Framework decorators appearing in domain entities
138 
139If SQLAlchemy `Column()` or Pydantic `Field()` annotations appear on domain entities, the entity is no longer pure. Create a separate ORM model in `adapters/repositories/` and map to/from the domain entity in the repository's `_to_entity()` method.
140 
141### All logic ending up in controllers
142 
143When the controller grows beyond HTTP parsing and response formatting, extract the logic into a use case class. A controller method should do three things only: parse the request, call a use case, map the response.
144 
145### Value objects raising errors too late
146 
147Validate invariants in `__post_init__` (Python) or the constructor so an invalid `Email` or `Money` cannot be constructed at all. This surfaces bad data at the boundary, not deep inside business logic.
148 
149### Context bleed across bounded contexts
150 
151If the `Order` context is importing `User` entities from the `Identity` context, introduce an Anti-Corruption Layer. The `Order` context should hold its own lightweight `CustomerId` value object and only call the `Identity` context through an explicit interface.
152 
153## Advanced Patterns
154 
155For detailed DDD bounded context mapping, full multi-service project trees, Anti-Corruption Layer implementations, and Onion Architecture comparisons, see:
156 
157- [`references/advanced-patterns.md`](references/advanced-patterns.md)
158 
159## Related Skills
160 
161- `microservices-patterns` — Apply these architecture patterns when decomposing a monolith into services
162- `cqrs-implementation` — Use Clean Architecture as the structural foundation for CQRS command/query separation
163- `saga-orchestration` — Sagas require well-defined aggregate boundaries, which DDD tactical patterns provide
164- `event-store-design` — Domain events produced by aggregates feed directly into an event store
165 

Reviews

Installed this one?Write the first review and take the Trailblazer badge.

Reviews only open after a real install, so this is empty — and we leave it empty rather than invent one.

Alternatives

Also in Coding