home / skills / masanao-ohba / claude-manifests / design-patterns

design-patterns skill

/skills/generic/design-patterns

This skill helps you apply software architecture and design patterns across layers, components, databases, and API design.

npx playbooks add skill masanao-ohba/claude-manifests --skill design-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.9 KB
---
name: design-patterns
description: Software design patterns for architecture, components, databases, and APIs
---

# Design Patterns

A technology-agnostic skill for software architecture and design patterns.

## Architectural Patterns

### Layered Architecture

```yaml
pattern: layered_architecture
description: "Separation of concerns through horizontal layers"

layers:
  presentation:
    responsibility: "User interface and input handling"
    communicates_with: [application]

  application:
    responsibility: "Business logic orchestration"
    communicates_with: [domain, infrastructure]

  domain:
    responsibility: "Core business rules and entities"
    communicates_with: [none - pure domain logic]

  infrastructure:
    responsibility: "External systems, persistence, APIs"
    communicates_with: [domain]

rules:
  - "Dependencies point inward (presentation → domain)"
  - "Each layer only knows about adjacent layers"
  - "Domain layer has no external dependencies"
```

### Clean Architecture

```yaml
pattern: clean_architecture
description: "Dependency inversion with entities at center"

rings:
  entities:
    description: "Enterprise business rules"
    dependencies: none

  use_cases:
    description: "Application business rules"
    dependencies: [entities]

  interface_adapters:
    description: "Controllers, presenters, gateways"
    dependencies: [use_cases, entities]

  frameworks:
    description: "External frameworks and drivers"
    dependencies: [interface_adapters]

key_principle: "Dependencies always point inward"
```

### Hexagonal Architecture (Ports & Adapters)

```yaml
pattern: hexagonal_architecture
description: "Core logic isolated from external concerns"

components:
  core:
    description: "Domain logic, independent of I/O"
    contains: [entities, services, ports]

  ports:
    description: "Interfaces defining boundaries"
    types:
      - primary: "Driven by external (API, UI)"
      - secondary: "Driving external (DB, messaging)"

  adapters:
    description: "Implementations connecting to external systems"
    examples:
      - "REST controller (primary adapter)"
      - "Repository implementation (secondary adapter)"

benefit: "Core can be tested without external systems"
```

## Component Design Patterns

### Repository Pattern

```yaml
pattern: repository
description: "Abstract data access behind collection-like interface"

structure:
  interface:
    methods:
      - "find(id): Entity"
      - "findAll(criteria): Entity[]"
      - "save(entity): void"
      - "delete(entity): void"

  implementation:
    responsibility: "Handle actual persistence"
    examples:
      - DatabaseRepository
      - InMemoryRepository
      - CacheDecoratorRepository

use_when:
  - "Separate domain from data access"
  - "Enable testing with in-memory implementations"
  - "Support multiple data sources"
```

### Service Pattern

```yaml
pattern: service
description: "Encapsulate business operations"

types:
  domain_service:
    description: "Operations that don't belong to a single entity"
    example: "TransferService for money transfers between accounts"

  application_service:
    description: "Orchestrate use cases"
    example: "OrderService coordinating payment, inventory, shipping"

  infrastructure_service:
    description: "External system interactions"
    example: "EmailService, PaymentGatewayService"

guidelines:
  - "Services are stateless"
  - "One public method per specific operation"
  - "Coordinate, don't contain business rules"
```

### Factory Pattern

```yaml
pattern: factory
description: "Encapsulate object creation logic"

types:
  simple_factory:
    use_when: "Creation logic is complex but static"
    example: "UserFactory.create(type)"

  factory_method:
    use_when: "Subclasses need to determine creation"
    example: "Abstract Document with createPage() method"

  abstract_factory:
    use_when: "Create families of related objects"
    example: "UIFactory creating buttons, dialogs, menus"

benefits:
  - "Centralize creation logic"
  - "Enforce invariants at creation"
  - "Support testing with mock factories"
```

## Database Design Patterns

### Entity Relationship Patterns

```yaml
patterns:
  one_to_many:
    description: "Parent has many children"
    implementation:
      - "Foreign key in child table"
      - "ON DELETE CASCADE if children are owned"
    example: "User has many Posts"

  many_to_many:
    description: "Both sides have many of each other"
    implementation:
      - "Junction/pivot table"
      - "Consider if junction has attributes"
    example: "Users and Roles via user_roles table"

  one_to_one:
    description: "Exactly one on each side"
    implementation:
      - "Foreign key with unique constraint"
      - "Or same primary key in both tables"
    example: "User has one Profile"
```

### Query Optimization Patterns

```yaml
optimization_patterns:
  indexing:
    description: "Speed up queries on specific columns"
    guidelines:
      - "Index columns in WHERE, JOIN, ORDER BY"
      - "Consider composite indexes for multi-column queries"
      - "Avoid over-indexing (slows writes)"

  eager_loading:
    description: "Load related data in fewer queries"
    use_when: "Always need related data"
    avoid_when: "Related data rarely used"

  pagination:
    description: "Limit result set size"
    techniques:
      - "LIMIT/OFFSET for simple cases"
      - "Cursor-based for large datasets"
```

## API Design Patterns

### RESTful Resource Design

```yaml
rest_patterns:
  resource_naming:
    rules:
      - "Use nouns, not verbs (/users, not /getUsers)"
      - "Use plural form (/users, not /user)"
      - "Use kebab-case for multi-word (/user-profiles)"
      - "Nest for relationships (/users/{id}/posts)"

  http_methods:
    GET: "Retrieve resource(s)"
    POST: "Create new resource"
    PUT: "Replace entire resource"
    PATCH: "Partial update"
    DELETE: "Remove resource"

  response_codes:
    200: "OK - Successful GET, PUT, PATCH"
    201: "Created - Successful POST"
    204: "No Content - Successful DELETE"
    400: "Bad Request - Invalid input"
    401: "Unauthorized - Auth required"
    403: "Forbidden - No permission"
    404: "Not Found - Resource doesn't exist"
    422: "Unprocessable - Validation failed"
    500: "Server Error - Unexpected failure"
```

### Request/Response Patterns

```yaml
patterns:
  envelope:
    description: "Wrap response in metadata"
    structure:
      data: "The actual response data"
      meta: "Pagination, timestamps, etc."
      errors: "Error details if applicable"

  hateoas:
    description: "Include links to related actions"
    example:
      data: {id: 1, name: "..."}
      links:
        self: "/users/1"
        posts: "/users/1/posts"
        delete: "/users/1"
```

## Integration

### Used By Agents

```yaml
primary_users:
  - design-architect: "Pattern selection and application"

secondary_users:
  - code-developer: "Implementing designed patterns"
  - quality-reviewer: "Validating pattern compliance"
```

Overview

This skill provides a technology-agnostic catalog of software design patterns for architecture, components, databases, and APIs. It helps teams choose, apply, and communicate proven structures for maintainable, testable systems. The content emphasizes clear responsibilities, dependency direction, and practical rules for implementation.

How this skill works

The skill organizes patterns by architectural style (layered, clean, hexagonal), component patterns (repository, service, factory), database modeling and query optimizations, and API design best practices. For each pattern it describes responsibilities, structure, usage rules, and common implementation variants to guide decisions and code organization. It is intended as a reference to align design choices, reduce coupling, and improve testability.

When to use it

  • Defining high-level architecture for a new system or major refactor
  • Separating domain logic from persistence or external systems
  • Standardizing component responsibilities for cross-team consistency
  • Designing database schemas and optimizing query performance
  • Establishing REST API naming, methods, and response conventions

Best practices

  • Keep dependencies pointing inward: domain and entities should have no external dependencies
  • Encapsulate data access behind repositories to enable in-memory testing and multiple data sources
  • Prefer stateless services that orchestrate use cases and delegate business rules to domain models
  • Use factories to centralize complex creation logic and enforce invariants at construction
  • Index columns used in WHERE, JOIN, and ORDER BY, but avoid over-indexing to preserve write performance
  • Design APIs around nouns, use appropriate HTTP verbs, and return clear status codes and envelope metadata when useful

Example use cases

  • Apply hexagonal architecture to isolate core domain logic and make adapters swappable for DB or messaging
  • Use a repository interface with an in-memory implementation for fast unit tests and a DB-backed implementation in production
  • Introduce a TransferService (domain service) for operations that span multiple entities without belonging to any single entity
  • Create pagination and cursor-based queries for large result sets and eager loading when related data is always required
  • Design REST resources with plural nouns, nested routes for relationships, and consistent response envelopes including meta and links

FAQ

How do I choose between layered and clean architecture?

Layered architecture is simple and suits many apps; choose clean architecture when you need stronger decoupling, explicit use-cases, and clearer dependency inversion for long-lived systems.

When should I use a repository vs direct ORM access?

Use a repository when you need a stable domain-facing API, multiple data sources, or easier testing. Direct ORM access is acceptable for small apps where extra abstraction adds little value.