d9e5668cec
Fixes and improvements from exhaustive audit: Consistency fixes in SKILL.md: - 'Pipe & Filter' → 'Pipe and Filter' (one stray '&' found and corrected) - 'Singleton for factory instance' → clarified to 'register factory as singleton-scoped via DI container' (less misleading wording) - Documentation Format section updated with note that SKILL.md itself is the authoritative source for related-pattern combinations Coverage fix — Related Patterns sections: - Added '## Related Patterns' to ALL 94 pattern files (was 0/94) - Each section lists 3–6 related patterns with relationship descriptions - Covers: why they're related, when to prefer one vs the other, and which are often confused SOLID principles → Creational → Structural → Behavioral → Architectural → Concurrency → Functional → Resilience → Data Access → Messaging → Testing → Error Handling → Microservice — all 13 categories covered Code verification: - Python: 0 failures (all 85 testable blocks pass) - Go: 0 failures (all 76 testable blocks pass) - JavaScript: 0 failures (all 78 testable blocks pass) - All 239 code blocks verified correct after edits Final skill state: - 108 files, 36,524 lines across 13 reference categories - 94/94 pattern files have Related Patterns sections - 2,815-line SKILL.md with 67 decision trees, 23 scenarios, 0 broken references, 0 naming inconsistencies
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 |