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
3.6 KiB
3.6 KiB
SOLID Principles — Overview
The SOLID principles are five design guidelines that make object-oriented software easier to understand, maintain, and extend. They were promoted by Robert C. Martin (Uncle Bob) and have become foundational to professional software engineering.
Quick-Reference Table
| Principle | Abbr. | One-Liner | Key Question |
|---|---|---|---|
| Single Responsibility | SRP | A class should have only one reason to change. | "Does this class do more than one job?" |
| Open/Closed | OCP | Open for extension, closed for modification. | "Can I add behavior without editing existing code?" |
| Liskov Substitution | LSP | Subtypes must be substitutable for their base types. | "Can I swap in a subclass without breaking anything?" |
| Interface Segregation | ISP | No client should depend on methods it does not use. | "Is any implementer forced to stub out unused methods?" |
| Dependency Inversion | DIP | Depend on abstractions, not concretions. | "Does my high-level logic import low-level details?" |
Decision Tree
Use the following decision tree when reviewing or designing code:
START: You are looking at a class / module / struct
│
├─ Does it have more than one reason to change?
│ YES → Apply SRP. Split into focused units.
│ NO ↓
│
├─ To add a new variant / behavior, must you edit existing code?
│ YES → Apply OCP. Introduce polymorphism or strategy.
│ NO ↓
│
├─ Can every subtype replace its parent without breaking callers?
│ NO → Apply LSP. Fix the inheritance hierarchy or use composition.
│ YES ↓
│
├─ Are implementers forced to depend on methods they don't use?
│ YES → Apply ISP. Break the interface into smaller, focused ones.
│ NO ↓
│
├─ Do high-level modules import / instantiate low-level concretions?
│ YES → Apply DIP. Introduce an abstraction and inject dependencies.
│ NO ↓
│
└─ Design looks solid. Review for other concerns (DRY, KISS, etc.)
How the Principles Relate
SRP ──► keeps units small and focused
│
OCP ──► lets you extend those units safely
│
LSP ──► guarantees substitutability in those extensions
│
ISP ──► prevents bloated contracts between units
│
DIP ──► decouples the wiring so everything stays flexible
- SRP + ISP often work together: splitting a fat class (SRP) usually means splitting its interface too (ISP).
- OCP + DIP are natural partners: depending on abstractions (DIP) is how you achieve extension without modification (OCP).
- LSP is the safety net: it ensures that the polymorphism you rely on for OCP actually works correctly.
When to Apply SOLID
Apply aggressively when:
- The codebase is long-lived and maintained by a team
- Requirements change frequently
- You are building libraries or frameworks consumed by others
- Testability is a priority
Apply with restraint when:
- Writing a one-off script or prototype
- The domain is tiny and unlikely to change
- Over-abstraction would add complexity without benefit
- You are in the earliest exploratory phase of a project
Files in This Directory
| File | Principle |
|---|---|
| single-responsibility.md | Single Responsibility Principle |
| open-closed.md | Open/Closed Principle |
| liskov-substitution.md | Liskov Substitution Principle |
| interface-segregation.md | Interface Segregation Principle |
| dependency-inversion.md | Dependency Inversion Principle |