SOLID Principles
SkillDev toolsSOLID Principles from Clean Architecture (Robert C. Martin). Use for code review, refactoring decisions, or when designing new modules/components.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the SOLID Principles skill
What this skill tells your AI
The instructions your AI receives, as published by dgouron/review-flow in .claude/skills/solid/SKILL.md and read by ahel’s review.
Apply when writing new code; check for violations when reviewing. Each principle below carries the smells that betray it in a diff.
S — Single Responsibility
One reason to change — one actor or stakeholder whose requirements could change the code.
Smells: a unit with more than one clear purpose (UserService that validates,
persists, and sends email); and in a name (validateAndSave()); functions
past ~30 lines; multiple unrelated tests for one unit.
If you cannot name a function without "and", it has too many jobs.
O — Open/Closed
Open for extension, closed for modification. Adding behavior should not require changing existing tested code.
Smells: a switch/if-else chain on a type field that must be edited for
every new type; hardcoded variant lists; tests that break whenever a new
variant is added.
Fix by defining an interface for the varying behavior and adding implementations rather than branches.
L — Liskov Substitution
Subtypes are substitutable for their base types without the caller knowing which it got.
Smells: an override that throws NotImplementedError or does nothing;
callers checking instanceof before calling; subclasses weakening
preconditions or strengthening postconditions; tests that cannot run against
both base and subtype.
Design hierarchies on behavior, not taxonomy. Prefer composition when "is-a"
does not hold behaviorally. A subtype may restrict behavior (ReadOnlyList)
but must fulfill every contract the base advertises.
I — Interface Segregation
No client depends on methods it does not call.
Smells: a 10-method interface whose implementers each use three; implementing
by throwing UnsupportedOperationException; test doubles that must stub many
irrelevant methods.
Split large interfaces; compose small ones when a concrete type needs several contracts.
D — Dependency Inversion
High-level modules and low-level modules both depend on abstractions. Business logic does not import database drivers, HTTP clients, or filesystem APIs directly.
Smells: domain classes that new their own dependencies; an infrastructure
import inside a domain service; tests that cannot run without a real database
or network. Two smells are easy to miss because the dependency is invisible in
the signature:
- Static calls into infrastructure (
Database.query(...),Clock.now(),Config.get(...)) have no seam, so tests cannot substitute them. - Singletons fetched inside business code (
Registry.getInstance()) make the class lie about what it needs.
Construct with collaborators. Call with work. The constructor takes the
long-lived collaborators that define what the object IS — its clients,
loggers, clock, database handle. Methods take the per-call work parameters. A
ReportGenerator(reportingDb, clock) serves many date ranges through
generate(startDate, endDate). A
ReportGenerator(reportingDb, clock, startDate, endDate) needs a new instance
per query and conflates identity with work.
In the reviewer role
Flag each violation by principle name, cite the file and line, and state the consequence — why this violation matters for this codebase right now:
issue: SRP violation — this function handles both input validation and the database write.
A finding that names no principle and no consequence is not actionable.
Signals
- GitHub stars
- 43
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
solid- Source
- github.com/dgouron/review-flow