Files
freemo 98680825a7 feat(skills): add exhaustive programming patterns agent skill
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
2026-04-15 13:21:51 -04:00

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