wpank

Architecture Patterns

開発v1.0.0
作者:wpank更新日 2026-05-11architecture-patterns@clawhub_wpank/architecture-patterns
コード生成バックエンド開発

AlphaMoatによると、2026-09時点でArchitecture Patternsのダウンロード数は4,822、スター数は10で、AIスキル全体5,078件中1,948位、開発では577件中250位です。

インストール数
153
ダウンロード数
4822
スター数
10
総合順位
#1,948
全体の上位 39% · 開発の上位 44%
プラットフォームインストール数ダウンロード数スター数コメント
ClawHub ↗15347087-
SkillHub ↗148482210—

プラットフォームごとに集計方法と集計時点が異なります。

このスキルでできること

Clean Architecture、Hexagonal Architecture、ドメイン駆動設計を扱い、新規システム、モノリスのリファクタリング、チーム標準の策定に使えます。カードは、決済アダプターの例はサンプルコードにすぎないと警告しています。実際の資格情報に接続する前に、認可、利用者確認、ログ、環境ごとの保護策を追加してください。 例は部分的な雛形で、プロジェクト固有のインターフェース・import・実装が必要です。単純な CRUD は過剰設計せず、実 DB や決済の前に連携境界を確認・テストしてください。

資料公開日 2026-10-27

できること

  • バックエンド設計パターンの適用場面を比べる
  • サービスのポート、アダプター、ドメインモデルを設計する

使う場面

  • バックエンドの設計やリファクタリングが目的で、サンプルコードを先に確認する場合

プロンプト例

スキルのドキュメントをもとに生成した例であり、実際の実行結果ではありません。

実際の決済資格情報に接続するコードを作らず、テスト性と保守性の観点から設計パターンを比較して。
決済アダプター設計を確認し、本番前に必要な認可と環境保護策を挙げて。

月次の推移

ダウンロード数4822
2848390849682026-03 · ダウンロード数 29942026-05 · ダウンロード数 37332026-06 · ダウンロード数 39242026-07 · ダウンロード数 43022026-08 · ダウンロード数 45412026-09 · ダウンロード数 482226-0326-09
スター数10
68102026-03 · スター数 62026-05 · スター数 72026-06 · スター数 62026-07 · スター数 92026-08 · スター数 102026-09 · スター数 1026-0326-09

2026-09 から集計方法を変更し、同名スキルを作者ごとに分けて集計し、全スキルを対象にしました。破線は変更前の月で、変更後のデータとは直接比較せず、変更をまたぐ増減も計算していません。 同名の別スキルがあるため、変更前のデータは現在ダウンロード数が最も多いこのスキルに帰属させています。

月ダウンロード数前月比スター数
2026-094822—10
2026-084541+5.6%10
2026-074302+9.6%9
2026-063924+5.1%6
2026-053733—7
2026-032994—6

SKILL.md 原文

作者が公開した元のファイルをテキストのまま表示しています。AlphaMoat による編集や審査はしていません。リンクはクリックできません。コマンドは内容を確認してから実行してください。取得日 2026-10-23。

11 KB・ClawHub v1.0.0
---
name: architecture-patterns
model: reasoning
---

# Architecture Patterns

## WHAT
Backend architecture patterns for building maintainable, testable systems: Clean Architecture, Hexagonal Architecture, and Domain-Driven Design.
すべて表示(全 356 行)
## WHEN
- Designing new backend systems from scratch
- Refactoring monoliths for better maintainability
- Establishing architecture standards for teams
- Creating testable, mockable codebases
- Planning microservices decomposition

## KEYWORDS
clean architecture, hexagonal, ports and adapters, DDD, domain-driven design, layers, entities, use cases, repositories, aggregates, bounded contexts

---

## Decision Framework: Which Pattern?

| Situation | Recommended Pattern |
|-----------|---------------------|
| Simple CRUD app | None (over-engineering) |
| Medium complexity, team standardization | Clean Architecture |
| Multiple external integrations that change frequently | Hexagonal (Ports & Adapters) |
| Complex business domain with many rules | Domain-Driven Design |
| Large system with multiple teams | DDD + Bounded Contexts |

## Quick Reference

### Clean Architecture Layers

```
┌──────────────────────────────────────┐
│      Frameworks & Drivers (UI, DB)   │  ← Outer: Can change
├──────────────────────────────────────┤
│      Interface Adapters              │  ← Controllers, Gateways
├──────────────────────────────────────┤
│      Use Cases                       │  ← Application Logic
├──────────────────────────────────────┤
│      Entities                        │  ← Core Business Rules
└──────────────────────────────────────┘
```

**Dependency Rule**: Dependencies point INWARD only. Inner layers never import outer layers.

### Hexagonal Architecture

```
         ┌─────────────┐
    ┌────│   Adapter   │────┐    (REST API)
    │    └─────────────┘    │
    ▼                       ▼
┌──────┐              ┌──────────┐
│ Port │◄────────────►│  Domain  │
└──────┘              └──────────┘
    ▲                       ▲
    │    ┌─────────────┐    │
    └────│   Adapter   │────┘    (Database)
         └─────────────┘
```

**Ports**: Interfaces defining what the domain needs
**Adapters**: Implementations (swappable for testing)

---

## Directory Structure

```
app/
├── domain/           # Entities & business rules (innermost)
│   ├── entities/
│   │   └── user.py
│   ├── value_objects/
│   │   └── email.py
│   └── interfaces/   # Ports
│       └── user_repository.py
├── use_cases/        # Application business rules
│   └── create_user.py
├── adapters/         # Interface implementations
│   ├── repositories/
│   │   └── postgres_user_repository.py
│   └── controllers/
│       └── user_controller.py
└── infrastructure/   # Framework & external concerns
    ├── database.py
    └── config.py
```

---

## Pattern 1: Clean Architecture

### Entity (Domain Layer)

```python
from dataclasses import dataclass
from datetime import datetime

@dataclass
class User:
    """Core entity - NO framework dependencies."""
    id: str
    email: str
    name: str
    created_at: datetime
    is_active: bool = True

    def deactivate(self):
        """Business rule in entity."""
        self.is_active = False

    def can_place_order(self) -> bool:
        return self.is_active
```

### Port (Interface)

```python
from abc import ABC, abstractmethod
from 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 Case (Application Layer)

```python
@dataclass
class CreateUserRequest:
    email: str
    name: str

@dataclass  
class CreateUserResponse:
    user: Optional[User]
    success: bool
    error: Optional[str] = None

class CreateUserUseCase:
    """Use case: orchestrates business logic."""
    
    def __init__(self, user_repository: IUserRepository):
        self.user_repository = user_repository  # Injected dependency
    
    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 exists")
        
        # Create entity
        user = User(
            id=str(uuid.uuid4()),
            email=request.email,
            name=request.name,
            created_at=datetime.now()
        )
        
        saved = await self.user_repository.save(user)
        return CreateUserResponse(user=saved, success=True)
```

### Adapter (Implementation)

```python
class PostgresUserRepository(IUserRepository):
    """Adapter: PostgreSQL implementation of the port."""
    
    def __init__(self, pool: asyncpg.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
```

---

## Pattern 2: Hexagonal (Ports & Adapters)

Best when you have multiple external integrations that may change.

```python
# Domain Service (Core)
class OrderService:
    def __init__(
        self,
        order_repo: OrderRepositoryPort,      # Port
        payment: PaymentGatewayPort,          # Port
        notifications: NotificationPort       # Port
    ):
        self.orders = order_repo
        self.payments = payment
        self.notifications = notifications
    
    async def place_order(self, order: Order) -> OrderResult:
        # Pure business logic - no infrastructure details
        if not order.is_valid():
            return OrderResult(success=False, error="Invalid order")
        
        payment = await self.payments.charge(order.total, order.customer_id)
        if not payment.success:
            return OrderResult(success=False, error="Payment failed")
        
        order.mark_as_paid()
        saved = await self.orders.save(order)
        await self.notifications.send(order.customer_email, "Order confirmed")
        
        return OrderResult(success=True, order=saved)

# Adapters (swap these for testing or changing providers)
class StripePaymentAdapter(PaymentGatewayPort):
    async def charge(self, amount: Money, customer: str) -> PaymentResult:
        # Real Stripe implementation
        ...

class MockPaymentAdapter(PaymentGatewayPort):
    async def charge(self, amount: Money, customer: str) -> PaymentResult:
        return PaymentResult(success=True, transaction_id="mock-123")
```

---

## Pattern 3: Domain-Driven Design

For complex business domains with many rules.

### Value Objects (Immutable)

```python
@dataclass(frozen=True)
class Email:
    """Value object: validated, immutable."""
    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)
```

### Aggregates (Consistency Boundaries)

```python
class Order:
    """Aggregate root: enforces invariants."""
    
    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):
        """Business logic in aggregate."""
        if quantity > product.max_quantity:
            raise ValueError(f"Max {product.max_quantity} allowed")
        
        item = OrderItem(product, quantity)
        self.items.append(item)
        self._events.append(ItemAddedEvent(self.id, item))
    
    def submit(self):
        """State transition with invariant enforcement."""
        if not self.items:
            raise ValueError("Cannot submit empty order")
        if self.status != OrderStatus.PENDING:
            raise ValueError("Order already submitted")
        
        self.status = OrderStatus.SUBMITTED
        self._events.append(OrderSubmittedEvent(self.id))
```

### Repository Pattern

```python
class OrderRepository:
    """Persist/retrieve aggregates, publish domain events."""
    
    async def save(self, order: Order):
        await self._persist(order)
        await self._publish_events(order._events)
        order._events.clear()
```

---

## Testing Benefits

All patterns enable the same testing approach:

```python
# Test with mock adapter
async def test_create_user():
    mock_repo = MockUserRepository()
    use_case = CreateUserUseCase(user_repository=mock_repo)
    
    result = await use_case.execute(CreateUserRequest(
        email="[email protected]",
        name="Test User"
    ))
    
    assert result.success
    assert result.user.email == "[email protected]"
```

---

## NEVER

- **Anemic Domain Models**: Entities with only data, no behavior (put logic IN entities)
- **Framework Coupling**: Business logic importing Flask, FastAPI, Django ORM
- **Fat Controllers**: Business logic in HTTP handlers
- **Leaky Abstractions**: Repository returning ORM objects instead of domain entities
- **Skipping Layers**: Controller directly accessing database
- **Over-Engineering**: Using Clean Architecture for simple CRUD apps
- **Circular Dependencies**: Use cases importing controllers

開発の人気スキル

wpankのその他のスキル

データ月:2026-09 · ダウンロード数、スター数、インストール数は公開スキルレジストリ(ClawHub、SkillHub)から月単位で集計しています。詳しくはデータの方法論をご覧ください。