100 lines
4.0 KiB
Markdown
100 lines
4.0 KiB
Markdown
---
|
|
name: system-decomposition
|
|
description: "Knowledge contract for splitting systems into services or modules, defining boundaries, data ownership, and dependency direction. Referenced by design-architecture when designing service boundaries."
|
|
---
|
|
|
|
This is a knowledge contract, not a workflow skill. It is referenced by `design-architecture` when the architect is designing service boundaries and system decomposition.
|
|
|
|
## Core Principles
|
|
|
|
- Each service or module must have a single, well-defined responsibility
|
|
- Data ownership must be clear: each piece of data belongs to exactly one service
|
|
- Dependencies must flow in one direction; cyclic dependencies are forbidden
|
|
- Boundaries must be drawn around domain responsibilities, not technical layers
|
|
|
|
## Decomposition Decisions
|
|
|
|
### Modular Monolith vs Microservices
|
|
|
|
Choose modular monolith when:
|
|
- Team size is small (fewer than 5-8 engineers per service boundary)
|
|
- Domain boundaries are still evolving
|
|
- Deployment simplicity is a priority
|
|
- Inter-service communication overhead would exceed in-process call overhead
|
|
- The PRD does not require independent scaling of individual services
|
|
|
|
Choose microservices when:
|
|
- Individual services have different scaling requirements stated in the PRD
|
|
- Team ownership aligns with service boundaries
|
|
- Domain boundaries are stable and well-understood
|
|
- Independent deployment of services is required
|
|
- The PRD explicitly requires isolation for reliability or security
|
|
|
|
Do not choose microservices solely because they are fashionable or because the team might need them someday. YAGNI applies.
|
|
|
|
### Domain Boundaries
|
|
|
|
Identify domain boundaries by looking for:
|
|
- Entities that change together
|
|
- Business rules that are cohesive
|
|
- Data that is accessed together
|
|
- User workflows that span a consistent context
|
|
|
|
A good boundary:
|
|
- Has high internal cohesion (related logic stays together)
|
|
- Has low external coupling (minimal cross-boundary calls)
|
|
- Can be understood independently
|
|
- Can be deployed independently if needed A bad boundary:
|
|
- Requires frequent cross-boundary calls to complete a workflow
|
|
- Splits closely related entities across services
|
|
- Exists because of technical layering rather than domain logic
|
|
- Requires distributed transactions to maintain consistency
|
|
|
|
### Coupling vs Cohesion
|
|
|
|
Favor high cohesion within a boundary:
|
|
- Related business rules live together
|
|
- Related data is owned by the same service
|
|
- Related workflows are handled end-to-end
|
|
|
|
Minimize coupling between boundaries:
|
|
- Communicate via well-defined contracts (APIs, events)
|
|
- Avoid sharing database tables between services
|
|
- Avoid synchronous call chains longer than 2 services deep when possible
|
|
- Prefer eventual consistency for cross-boundary state updates
|
|
|
|
### State Ownership
|
|
|
|
Each piece of state must have exactly one owner:
|
|
- The owning service is the single source of truth
|
|
- Other services access that state via the owner's API or events
|
|
- No service reads directly from another service's database
|
|
- If data is needed in multiple places, replicate via events with a clear source of truth
|
|
|
|
## Communication Patterns
|
|
|
|
### Synchronous
|
|
- Use when the caller needs an immediate response
|
|
- Use for queries and command validation
|
|
- Avoid for long-running operations
|
|
- Consider timeouts and circuit breakers
|
|
|
|
### Asynchronous
|
|
- Use when the caller does not need an immediate response
|
|
- Use for events, notifications, and eventual consistency
|
|
- Use when decoupling producer and consumer is valuable
|
|
- Consider ordering, retry, and DLQ requirements
|
|
|
|
### Event-Driven
|
|
- Use when multiple consumers need to react to state changes
|
|
- Use for cross-boundary consistency (eventual)
|
|
- Define event schemas explicitly
|
|
- Consider event versioning and backward compatibility
|
|
|
|
## Anti-Patterns
|
|
|
|
- Distributed monolith: microservices that must be deployed together
|
|
- Shared database: multiple services reading/writing the same tables
|
|
- Synchronous chain: 3+ services in a synchronous call chain
|
|
- Leaky domain: business rules that require data from other services directly instead of via APIs or events
|
|
- Premature decomposition: splitting before boundaries are understood |