Architecture Patterns

作者 secondsky88378361314fMIT227 个星标收录于 2026年10月8日更新于 2026年10月8日仓库10天前更新

Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use when architecting complex backend systems or refactoring existing applications for better maintainability.

AI 生成的概览

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

功能
该技能提供关于成熟后端架构模式的参考指导:整洁架构、六边形(端口与适配器)架构以及领域驱动设计。它讲解分层、端口、适配器、限界上下文、实体、值对象、聚合与仓储,并用 Python 代码示例加以说明。它还列出最佳实践与常见陷阱,例如贫血领域模型、框架耦合与过度设计。
适用场景
适用于从零设计新的后端系统、为提升可维护性而重构单体应用、为团队制定架构标准,或规划微服务拆分。也适合应用领域驱动设计原则,或追求可测试、低耦合代码库的场景。
运行要求
无需脚本或工具,仅为说明与参考资料。代码示例使用 Python,但不需要运行时、依赖包、凭据或网络访问。

Architecture Patterns

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

When to Use This Skill

  • Designing new backend systems from scratch
  • Refactoring monolithic applications for better maintainability
  • Establishing architecture standards for your team
  • Migrating from tightly coupled to loosely coupled architectures
  • Implementing domain-driven design principles
  • Creating testable and mockable codebases
  • Planning microservices decomposition

Core Concepts

1. Clean Architecture (Uncle Bob)

Layers (dependency flows inward):

  • Entities: Core business models
  • Use Cases: Application business rules
  • Interface Adapters: Controllers, presenters, gateways
  • Frameworks & Drivers: UI, database, external services

Key Principles:

  • Dependencies point inward
  • Inner layers know nothing about outer layers
  • Business logic independent of frameworks
  • Testable without UI, database, or external services

2. Hexagonal Architecture (Ports and Adapters)

Components:

  • Domain Core: Business logic
  • Ports: Interfaces defining interactions
  • Adapters: Implementations of ports (database, REST, message queue)

Benefits:

  • Swap implementations easily (mock for testing)
  • Technology-agnostic core
  • Clear separation of concerns

3. Domain-Driven Design (DDD)

Strategic Patterns:

  • Bounded Contexts: Separate models for different domains
  • Context Mapping: How contexts relate
  • Ubiquitous Language: Shared terminology

Tactical Patterns:

  • Entities: Objects with identity
  • Value Objects: Immutable objects defined by attributes
  • Aggregates: Consistency boundaries
  • Repositories: Data access abstraction
  • Domain Events: Things that happened

Clean Architecture Pattern

Directory Structure

app/├── domain/           # Entities & business rules│   ├── entities/│   ├── value_objects/│   └── interfaces/   # Abstract interfaces├── use_cases/        # Application business rules├── adapters/         # Interface implementations│   ├── repositories/│   ├── controllers/│   └── gateways/└── infrastructure/   # Framework & external concerns

Implementation Example

python
# domain/entities/user.pyfrom dataclasses import dataclassfrom datetime import datetime
@dataclassclass User:    """Core user entity - no framework dependencies."""    id: str    email: str    name: str    created_at: datetime    is_active: bool = True
    def deactivate(self):        """Business rule: deactivating user."""        self.is_active = False
    def can_place_order(self) -> bool:        """Business rule: active users can order."""        return self.is_active
# domain/interfaces/user_repository.pyfrom abc import ABC, abstractmethodfrom typing import Optional
class IUserRepository(ABC):    """Port: defines contract, no implementation."""
    @abstractmethod    async def find_by_id(self, user_id: str) -> Optional[User]:        pass
    @abstractmethod    async def save(self, user: User) -> User:        pass
# use_cases/create_user.pyfrom dataclasses import dataclassimport uuidfrom datetime import datetime
@dataclassclass CreateUserRequest:    email: str    name: str
class CreateUserUseCase:    """Use case: orchestrates business logic."""
    def __init__(self, user_repository: IUserRepository):        self.user_repository = user_repository
    async def execute(self, request: CreateUserRequest) -> CreateUserResponse:        # Business validation        existing = await self.user_repository.find_by_email(request.email)        if existing:            return CreateUserResponse(user=None, success=False, error="Email already exists")
        # Create entity        user = User(            id=str(uuid.uuid4()),            email=request.email,            name=request.name,            created_at=datetime.now(),            is_active=True        )
        # Persist        saved_user = await self.user_repository.save(user)        return CreateUserResponse(user=saved_user, success=True)
# adapters/repositories/postgres_user_repository.pyclass PostgresUserRepository(IUserRepository):    """Adapter: PostgreSQL implementation."""
    def __init__(self, pool):        self.pool = pool
    async def find_by_id(self, user_id: str) -> Optional[User]:        async with self.pool.acquire() as conn:            row = await conn.fetchrow("SELECT * FROM users WHERE id = $1", user_id)            return self._to_entity(row) if row else None
    async def save(self, user: User) -> User:        async with self.pool.acquire() as conn:            await conn.execute(                """INSERT INTO users (id, email, name, created_at, is_active)                VALUES ($1, $2, $3, $4, $5)                ON CONFLICT (id) DO UPDATE SET email = $2, name = $3, is_active = $5""",                user.id, user.email, user.name, user.created_at, user.is_active            )            return user

Hexagonal Architecture Pattern

python
# Core domain (hexagon center)class OrderService:    """Domain service - no infrastructure dependencies."""
    def __init__(        self,        order_repository: OrderRepositoryPort,        payment_gateway: PaymentGatewayPort,        notification_service: NotificationPort    ):        self.orders = order_repository        self.payments = payment_gateway        self.notifications = notification_service
    async def place_order(self, order: Order) -> OrderResult:        # Business logic        if not order.is_valid():            return OrderResult(success=False, error="Invalid order")
        # Use ports (interfaces)        payment = await self.payments.charge(amount=order.total, customer=order.customer_id)
        if not payment.success:            return OrderResult(success=False, error="Payment failed")
        order.mark_as_paid()        saved_order = await self.orders.save(order)
        await self.notifications.send(            to=order.customer_email,            subject="Order confirmed",            body=f"Order {order.id} confirmed"        )
        return OrderResult(success=True, order=saved_order)
# Adaptersclass StripePaymentAdapter(PaymentGatewayPort):    """Primary adapter: connects to Stripe API."""    async def charge(self, amount: Money, customer: str) -> PaymentResult:        # Implementation
class MockPaymentAdapter(PaymentGatewayPort):    """Test adapter: no external dependencies."""    async def charge(self, amount: Money, customer: str) -> PaymentResult:        return PaymentResult(success=True, transaction_id="mock-123")

Domain-Driven Design Pattern

python
# Value Objects (immutable)@dataclass(frozen=True)class Email:    value: str
    def __post_init__(self):        if "@" not in self.value:            raise ValueError("Invalid email")
@dataclass(frozen=True)class Money:    amount: int  # cents    currency: str
    def add(self, other: "Money") -> "Money":        if self.currency != other.currency:            raise ValueError("Currency mismatch")        return Money(self.amount + other.amount, self.currency)
# Entities (with identity)class Order:    def __init__(self, id: str, customer: Customer):        self.id = id        self.customer = customer        self.items: List[OrderItem] = []        self.status = OrderStatus.PENDING        self._events: List[DomainEvent] = []
    def add_item(self, product: Product, quantity: int):        item = OrderItem(product, quantity)        self.items.append(item)        self._events.append(ItemAddedEvent(self.id, item))
    def submit(self):        if not self.items:            raise ValueError("Cannot submit empty order")        self.status = OrderStatus.SUBMITTED        self._events.append(OrderSubmittedEvent(self.id))
# Aggregates (consistency boundary)class Customer:    def __init__(self, id: str, email: Email):        self.id = id        self.email = email        self._addresses: List[Address] = []
    def add_address(self, address: Address):        if len(self._addresses) >= 5:            raise ValueError("Maximum 5 addresses allowed")        self._addresses.append(address)

Best Practices

  1. Dependency Rule: Dependencies always point inward
  2. Interface Segregation: Small, focused interfaces
  3. Business Logic in Domain: Keep frameworks out of core
  4. Test Independence: Core testable without infrastructure
  5. Bounded Contexts: Clear domain boundaries
  6. Ubiquitous Language: Consistent terminology
  7. Thin Controllers: Delegate to use cases
  8. Rich Domain Models: Behavior with data

Common Pitfalls

  • Anemic Domain: Entities with only data, no behavior
  • Framework Coupling: Business logic depends on frameworks
  • Fat Controllers: Business logic in controllers
  • Repository Leakage: Exposing ORM objects
  • Missing Abstractions: Concrete dependencies in core
  • Over-Engineering: Clean architecture for simple CRUD

来源与署名

来源:secondsky/claude-skills位于plugins/architecture-patterns/skills/architecture-patterns提交8837836

许可证: MIT

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

举报或申请下架