Architecture Patterns

作者 wshobson46891e7e60da无许可证收录于 2026年10月8日更新于 2026年10月8日

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.

AI 生成的概览

指导后端架构设计,涵盖整洁架构、六边形架构与领域驱动设计模式。

功能
讲解分层架构概念,如实体、用例、适配器、端口、限界上下文、聚合与值对象。针对某个服务边界或模块,产出分层结构建议,包括依赖规则、接口定义与测试边界。还涵盖依赖循环、领域实体中出现框架装饰器、上下文串扰等问题的排查,并指向随附参考文件以了解进阶模式。
适用场景
适用于从零设计新的后端服务或微服务、重构业务逻辑与 ORM 或 HTTP 关注点纠缠的单体应用、在拆分系统前划定限界上下文,或排查应用层之间的依赖循环。也适合希望用例测试无需数据库即可运行的场景。不适用于编写应用功能或部署工作。
运行要求
无需脚本或工具,仅提供说明。它引用两个随附的参考文件(references/details.md 与 references/advanced-patterns.md),由代理读取以获取更深入的细节。代码示例为示意性 Python。

Architecture Patterns

Master proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design to build maintainable, testable, and scalable systems.

Given: a service boundary or module to architect. Produces: layered structure with clear dependency rules, interface definitions, and test boundaries.

When to Use This Skill

  • Designing new backend services or microservices from scratch
  • Refactoring monolithic applications where business logic is entangled with ORM models or HTTP concerns
  • Establishing bounded contexts before splitting a system into services
  • Debugging dependency cycles where infrastructure code bleeds into the domain layer
  • Creating testable codebases where use-case tests do not require a running database
  • Implementing domain-driven design tactical patterns (aggregates, value objects, domain events)

Core Concepts

1. Clean Architecture (Uncle Bob)

Layers (dependency flows inward):

  • Entities: Core business models, no framework imports
  • Use Cases: Application business rules, orchestrate entities
  • Interface Adapters: Controllers, presenters, gateways — translate between use cases and external formats
  • Frameworks & Drivers: UI, database, external services — all at the outermost ring

Key Principles:

  • Dependencies point inward only; inner layers know nothing about outer layers
  • Business logic is independent of frameworks, databases, and delivery mechanisms
  • Every layer boundary is crossed via an abstract interface
  • Testable without UI, database, or external services

2. Hexagonal Architecture (Ports and Adapters)

Components:

  • Domain Core: Business logic lives here, framework-free
  • Ports: Abstract interfaces that define how the core interacts with the outside world (driving and driven)
  • Adapters: Concrete implementations of ports (PostgreSQL adapter, Stripe adapter, REST adapter)

Benefits:

  • Swap implementations without touching the core (e.g., replace PostgreSQL with DynamoDB)
  • Use in-memory adapters in tests — no Docker required
  • Technology decisions deferred to the edges

3. Domain-Driven Design (DDD)

Strategic Patterns:

  • Bounded Contexts: Isolate a coherent model for one subdomain; avoid sharing a single model across the whole system
  • Context Mapping: Define how contexts relate (Anti-Corruption Layer, Shared Kernel, Open Host Service)
  • Ubiquitous Language: Every term in code matches the term used by domain experts

Tactical Patterns:

  • Entities: Objects with stable identity that change over time
  • Value Objects: Immutable objects identified by their attributes (Email, Money, Address)
  • Aggregates: Consistency boundaries; only the root is accessible from outside
  • Repositories: Persist and reconstitute aggregates; abstract over the storage mechanism
  • Domain Events: Capture things that happened inside the domain; used for cross-aggregate coordination

Detailed patterns and worked examples

Detailed pattern documentation lives in references/details.md. Read that file when the navigation tier above is insufficient.

Testing — In-Memory Adapters

The 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:

python
# tests/unit/test_create_user.pyimport asynciofrom typing import Dict, Optionalfrom domain.entities.user import Userfrom domain.interfaces.user_repository import IUserRepositoryfrom use_cases.create_user import CreateUserUseCase, CreateUserRequest
class InMemoryUserRepository(IUserRepository):    def __init__(self):        self._store: Dict[str, User] = {}
    async def find_by_id(self, user_id: str) -> Optional[User]:        return self._store.get(user_id)
    async def find_by_email(self, email: str) -> Optional[User]:        return next((u for u in self._store.values() if u.email == email), None)
    async def save(self, user: User) -> User:        self._store[user.id] = user        return user
    async def delete(self, user_id: str) -> bool:        return self._store.pop(user_id, None) is not None
async def test_create_user_succeeds():    repo = InMemoryUserRepository()    use_case = CreateUserUseCase(user_repository=repo)
    response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))
    assert response.success    assert response.user.email == "[email protected]"    assert response.user.id is not None
async def test_duplicate_email_rejected():    repo = InMemoryUserRepository()    use_case = CreateUserUseCase(user_repository=repo)
    await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))    response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice2"))
    assert not response.success    assert "already exists" in response.error

Troubleshooting

Use case tests require a running database

Business 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.

Circular imports between layers

A 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/.

Framework decorators appearing in domain entities

If 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.

All logic ending up in controllers

When 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.

Value objects raising errors too late

Validate 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.

Context bleed across bounded contexts

If 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.

Advanced Patterns

For detailed DDD bounded context mapping, full multi-service project trees, Anti-Corruption Layer implementations, and Onion Architecture comparisons, see:

  • references/advanced-patterns.md [blocked]

Related Skills

  • microservices-patterns — Apply these architecture patterns when decomposing a monolith into services
  • cqrs-implementation — Use Clean Architecture as the structural foundation for CQRS command/query separation
  • saga-orchestration — Sagas require well-defined aggregate boundaries, which DDD tactical patterns provide
  • event-store-design — Domain events produced by aggregates feed directly into an event store

来源与署名

来源:wshobson/agents位于plugins/backend-development/skills/architecture-patterns提交46891e7

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架