AgentSkillsCN

architecture-patterns

可扩展系统的软件架构模式与设计原则。

SKILL.md
--- frontmatter
name: architecture-patterns
description: Software architecture patterns and design principles for scalable systems

Architecture Patterns Skill

Overview

Software architecture decision frameworks and patterns. Provides guidance on when to use which patterns, API design, data layer patterns, and common anti-patterns to avoid.

Type

reference

When to Invoke

Trigger keywords: architecture, design pattern, API design, microservices, data layer, CQRS, repository pattern, clean architecture, DDD

Trigger phrases:

  • "how should I structure..."
  • "what pattern should I use"
  • "microservices vs monolith"
  • "API design for..."
  • "data access pattern"

Architecture Decision Framework

When making architectural decisions, ask:

1. Scale Questions

  • Current user count? Expected growth?
  • Request volume? Peaks?
  • Data volume? Growth rate?
  • Team size? Expected growth?

2. Complexity Questions

  • How many bounded contexts/domains?
  • Integration requirements?
  • Real-time requirements?
  • Consistency requirements (strong vs eventual)?

3. Constraint Questions

  • Budget constraints?
  • Timeline pressure?
  • Team expertise?
  • Regulatory/compliance needs?

Application Architecture Patterns

Monolith

Use when:

  • Starting new project
  • Small team (1-5 developers)
  • Single domain
  • Need to move fast

Avoid when:

  • Multiple teams
  • Independent scaling needed
  • Different deployment schedules
code
┌─────────────────────────────────────┐
│           MONOLITH                  │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐   │
│  │ UI  │ │Users│ │Order│ │ Pay │   │
│  └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘   │
│     └───────┴───────┴───────┘       │
│              Database               │
└─────────────────────────────────────┘

Modular Monolith

Use when:

  • Growing monolith
  • Preparing for microservices
  • Need better boundaries
  • Team growing
code
┌─────────────────────────────────────┐
│        MODULAR MONOLITH             │
│  ┌─────────┐  ┌─────────┐           │
│  │ Users   │  │ Orders  │           │
│  │ Module  │  │ Module  │  ...      │
│  └────┬────┘  └────┬────┘           │
│       │            │                │
│  ┌────┴────┐  ┌────┴────┐           │
│  │Users DB │  │Orders DB│           │
│  └─────────┘  └─────────┘           │
└─────────────────────────────────────┘

Microservices

Use when:

  • Large team (10+ developers)
  • Independent deployability critical
  • Different scaling requirements
  • Clear domain boundaries

Avoid when:

  • Small team
  • Unclear boundaries
  • Premature optimization
code
┌─────────┐    ┌─────────┐    ┌─────────┐
│ Users   │    │ Orders  │    │ Payment │
│ Service │◄──►│ Service │◄──►│ Service │
└────┬────┘    └────┬────┘    └────┬────┘
     │              │              │
┌────┴────┐   ┌────┴────┐    ┌────┴────┐
│Users DB │   │Orders DB│    │Payments │
└─────────┘   └─────────┘    │   DB    │
                             └─────────┘

API Design Patterns

REST

Use when:

  • Resource-based operations (CRUD)
  • HTTP semantics fit well
  • Simple client needs
  • Caching important
code
GET    /users           # List users
GET    /users/{id}      # Get user
POST   /users           # Create user
PUT    /users/{id}      # Update user
DELETE /users/{id}      # Delete user

GraphQL

Use when:

  • Complex, nested data requirements
  • Multiple client types (web, mobile)
  • Over-fetching is a problem
  • Rapid frontend iteration
graphql
query GetUser($id: ID!) {
  user(id: $id) {
    name
    orders {
      id
      total
      items { name }
    }
  }
}

gRPC

Use when:

  • Service-to-service communication
  • Performance critical
  • Strong typing required
  • Streaming needed
protobuf
service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc StreamUpdates(Empty) returns (stream UserUpdate);
}

Decision Matrix

FactorRESTGraphQLgRPC
Learning curveLowMediumHigh
ToolingExcellentGoodGrowing
PerformanceGoodGoodExcellent
Browser supportNativeNativeLimited
CachingExcellentComplexLimited

Data Access Patterns

Repository Pattern

Use when:

  • Need to abstract data access
  • Unit testing with mocks
  • Potential DB changes
python
class UserRepository:
    def get(self, id: str) -> User:
        ...
    def save(self, user: User) -> None:
        ...
    def delete(self, id: str) -> None:
        ...

CQRS (Command Query Responsibility Segregation)

Use when:

  • Read and write loads differ
  • Complex read models
  • Event sourcing
code
Commands (Writes)          Queries (Reads)
     │                          │
     ▼                          ▼
┌─────────┐              ┌─────────┐
│ Command │              │  Query  │
│ Handler │              │ Handler │
└────┬────┘              └────┬────┘
     │                        │
     ▼                        ▼
┌─────────┐              ┌─────────┐
│ Write   │   ──sync──►  │  Read   │
│   DB    │              │   DB    │
└─────────┘              └─────────┘

Event Sourcing

Use when:

  • Complete audit trail required
  • Time-travel debugging valuable
  • Complex domain logic
code
Events: [
  UserCreated(id=1, name="Alice"),
  UserEmailChanged(id=1, email="alice@new.com"),
  UserDeactivated(id=1)
]
Current State: { id: 1, name: "Alice", email: "alice@new.com", active: false }

Layer Architecture

Clean Architecture / Hexagonal

code
┌──────────────────────────────────────────┐
│              Presentation                 │
│         (Controllers, Views)              │
├──────────────────────────────────────────┤
│              Application                  │
│          (Use Cases, DTOs)               │
├──────────────────────────────────────────┤
│               Domain                      │
│      (Entities, Business Rules)          │
├──────────────────────────────────────────┤
│            Infrastructure                 │
│    (Database, External Services)         │
└──────────────────────────────────────────┘

Dependency Rule: Dependencies point inward. Domain has no external dependencies.

Anti-Patterns to Avoid

Anti-PatternProblemSolution
Big Ball of MudNo structure, tangled codeModular design, clear boundaries
Distributed MonolithMicroservices with couplingTrue boundaries, event-driven
God ObjectOne class does everythingSingle responsibility, decompose
Anemic DomainLogic in services, not entitiesRich domain models
Leaky AbstractionImplementation details exposedProper encapsulation
Premature OptimizationOver-engineering for scaleStart simple, measure, optimize
Cargo Cult ArchitectureCopying without understandingUnderstand patterns first

Pattern Selection Algorithm

code
Is domain complex?
├─ No → Monolith with simple layers
└─ Yes →
    Is team large (10+)?
    ├─ No → Modular Monolith
    └─ Yes →
        Are boundaries clear?
        ├─ No → Define domains first (DDD)
        └─ Yes → Microservices

Integration

Works with:

  • project-scaffolding - Structure based on chosen pattern
  • documentation-standards - Document architectural decisions
  • /newapp command - Invokes during planning phase

Reference patterns from DDD, Clean Architecture, and microservices literature