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 從公開儲存庫中收錄這些內容。

檢舉或申請下架