98680825a7
Adds a comprehensive opencode skill under .opencode/skills/programming-patterns/
covering 90+ design, architectural, concurrency, and functional patterns.
- 108 files, 33,500+ lines across 13 reference categories
- Every pattern: pseudocode + tested Python + Go + JavaScript implementations
- All 239 code blocks verified passing (85 Python, 76 Go, 78 JS)
- 1,569-line SKILL.md with:
- Master decision tree (all 14 categories with multi-pattern suggestions)
- 34 situation-specific decision trees covering every programming scenario
(new feature, refactoring, REST API, CLI, data pipeline, rule engine,
external integration, performance, memory, notifications, plugins,
caching, events, auth, reporting, vendor lock-in, domain model,
business rules, observability, file I/O, scheduling, testability,
third-party libs, concurrency, complex domain interactions)
- 12 compound pattern-combination scenarios with full architecture maps
(e-commerce checkout, REST endpoint, background jobs, real-time dashboard,
microservice resilience, ML pipeline, text editor, legacy migration,
multi-tenant SaaS, document approval, financial transactions, chat)
- 'When Am I Allowed to Skip Patterns?' mandate table (answer: never)
- Quick pattern lookup tables for all 90+ patterns
- Complete reference index
2.2 KiB
2.2 KiB
Data Access Patterns
Data access patterns define how application code interacts with persistent storage — databases, files, caches. They address the impedance mismatch between object-oriented domain models and relational or document-based storage, while managing concerns like identity, loading strategy, and data transfer boundaries.
Pattern Comparison
| Pattern | Purpose | Complexity | Best For |
|---|---|---|---|
| Active Record | Domain object handles its own CRUD | Low | Simple domains, rapid prototyping |
| Data Mapper | Separate mapper layer between domain and DB | High | Complex domains, clean architecture |
| Identity Map | Cache loaded objects by ID, avoid duplicates | Medium | ORM internals, unit-of-work |
| Lazy Loading | Defer data loading until first access | Medium | Object graphs with optional relations |
| DTO | Transfer data across boundaries without behavior | Low | API layers, serialization |
| Value Object | Immutable, identity-free domain values | Low | Money, coordinates, date ranges |
| Aggregate | Cluster of objects treated as a unit | High | DDD, transactional consistency |
Decision Guide
Is your domain model simple (few relations, straightforward CRUD)?
├─ Yes → Active Record
└─ No → Data Mapper + Identity Map
│
├─ Do objects have large relation graphs?
│ └─ Yes → Add Lazy Loading
│
├─ Do you pass data across layers/APIs?
│ └─ Yes → Use DTOs at boundaries
│
├─ Do you have small immutable concepts (money, email)?
│ └─ Yes → Model as Value Objects
│
└─ Do you need transactional consistency across multiple objects?
└─ Yes → Define Aggregates
Key Principles
- Separate concerns — Domain logic should not depend on storage mechanics.
- Manage identity explicitly — Know when two references point to the same entity.
- Load only what you need — Eager loading wastes resources; lazy loading risks N+1.
- Protect boundaries — Don't leak domain objects into API responses (use DTOs).
- Design for consistency — Aggregates define transactional boundaries.