ryanthedev/code-foundations/cc-routine-and-class-design
Claude Code and agent skill by ryanthedev/code-foundations
- community
Checking that the SKILL.md file is still in the repository.
Applies Code Complete's routine and class design rules at the routine level: cohesion classification, parameter-count thresholds, LSP inheritance verification, and containment-vs-inheritance decision. For routine and class scope, not system architecture (use ca-architecture-boundaries).
Install
npx vskill@latest install ryanthedev/code-foundations/cc-routine-and-class-designSKILL.md
cc-routine-and-class-design
Three checks catch design problems that can't be patched post-hoc (they require architectural change, not a fix):
| Check | What | |
|---|---|---|
| LSP test | Is "A is a B" literally true? If not, the inheritance is wrong | |
| Containment default | If LSP feels like purity theater, use containment — it's fixable; inheritance isn't | |
| Parameter count | Over 7 parameters predicts interface errors — the interface is wrong |
A passing test suite does not clear these: code can pass all tests on day 1 and still carry VIOLATION-level design debt that surfaces during later modification.
Shared thresholds (parameters 7±2, inheritance depth, routine length, cohesion spectrum): Read(${CLAUDE_PLUGIN_ROOT}/references/cc-foundations.md).
When NOT to apply
- One-off scripts and automation.
- Prototyping (time-boxed before committing to a design).
- Pure DTOs without behavior (but DTOs with validation/equals/toString are NOT exempt).
- Framework-mandated inheritance (e.g. Android
Activity) — but "framework examples use inheritance" is not a mandate. - Profiled performance-critical inner loops (show the data).
- Test doubles — empty overrides and minimal abstractions are appropriate in test code.
Modes
CHECKER
Execute the design checklists against routines and classes: Read(${CLAUDE_SKILL_DIR}/checklists.md). CHECKER output: the ID'd checklist is the item set (the tables in this SKILL.md explain the items, they are not counted twice). Report each VIOLATION and WARNING as | Item | Status | Evidence | Location |; do not list passing or non-applicable items — close with one line N items checked, M pass, K n/a.
| Severity | Criteria | |
|---|---|---|
| VIOLATION | Fails a checklist item (e.g. 10+ params); breaks LSP/encapsulation (empty override, protected base data) | |
| WARNING | Near a limit needing justification (8–9 params, 3-level inheritance); a subjective abstraction concern | |
| PASS | Meets or exceeds the requirement — counted in M pass, not listed |
APPLIER
Produce class interface designs, inheritance/containment decisions, routine signatures, and cohesion classifications.
- Default to containment; inherit only if "is-a" is literally true (LSP) [p.133].
- Inheritance depth: target <3, WARNING at 3, VIOLATION at 4+, SEVERE at 6+ [p.143].
- Parameters: 7 maximum, graduated per the table below [p.178].
- Target functional cohesion [p.168].
- Ask "What should this class hide?" to drive the design [p.139].
Parameter thresholds
| Count | Status | Action | |
|---|---|---|---|
| 1–5 | PASS | None | |
| 6–7 | PASS | Minor concern; document if unusual | |
| 8–9 | WARNING | Justify in review or redesign | |
| 10+ | VIOLATION | Redesign — parameter object or split responsibilities |
Count all parameters including defaulted ones; variadic (*args/...) counts as 1. Ordering convention (order implies data flow): input-only first, input-output second, output-only third.
LSP
If A inherits from B, every place that uses B can substitute A without breaking. Inheritance requires both:
- Semantic: "A is a B" makes sense to a domain expert (Dog is an Animal — yes; UserSession is a Logger — no).
- LSP: every method of B works when A is substituted — no empty overrides, no new exceptions the base doesn't throw, no strengthened preconditions.
If either fails, use containment.
Inheritance vs containment decision
- Shares only data → contain a common object.
- Shares only behavior (method signatures) → use an interface/protocol, not inheritance.
- Shares both data and behavior → inherit only if "A is a B" is literally true (LSP); otherwise contain.
FINAL CHECK (after deciding INHERIT, before committing): depth < 3 (definitely < 6)? No empty overrides needed? All base data private (not protected)? If any answer is NO → contain instead.
Functional cohesion
A routine performs one and only one operation. If you need "and" or "then" to name it, it has multiple operations.
- PASS:
ValidateUserInput(),CalculateTotalPrice(),SendWelcomeEmail(). - FAIL:
ValidateAndSaveUser(),ReadFileThenParseJSON().
"One operation" is at the routine's declared abstraction level: CreateUser() is one operation even though it validates, hashes, and inserts — those are at a lower level.
Cohesion classification (best to worst — stop at the first match)
| Type | Definition | Verdict | |
|---|---|---|---|
| Functional | One and only one operation | ACCEPT | |
| Sequential | Operations share data step-to-step in required order | ACCEPT w/caution | |
| Communicational | Operations use the same data but are otherwise unrelated | ACCEPT w/caution | |
| Temporal | Combined because done at the same time (startup/shutdown) | ACCEPT if it orchestrates calls; FIX if it does the work directly | |
| Procedural | Ordered by external requirement (UI flow), not logic | REJECT | |
| Logical | A control flag selects one of several unrelated operations | REJECT | |
| Coincidental | No discernible relationship | REDESIGN |
"ACCEPT w/caution" = document why this type is acceptable here, review whether functional cohesion is reachable, and add a TODO if it should improve. Caution is permission with accountability, not permission to ignore.
Detecting orchestration (temporal OK): verbs like orchestrates/coordinates/delegates/dispatches/routes suggest orchestration (calls other routines). Verbs like handles/processes/performs/calculates suggest direct work — check the cohesion type and extract the direct work into named routines.
Improving cohesion
| Type | Steps | |
|---|---|---|
| Sequential | Split per operation; have the dependent routine call what it depends on | |
| Communicational | Split into individual routines; reinitialize data near creation; call both from a higher level | |
| Temporal | Make the routine an organizer that calls doers; name at the right abstraction level | |
| Logical | One routine per distinct operation; move shared code lower; package into a class |
Pattern-specific guidance
- Builder — evaluate cohesion at the class level; methods returning
thisare fine; class cohesion = "constructs one type of object". - Mixin/trait — single focused responsibility, fewer than 3 per class; prefer containment, which makes the relationship explicit.
- Singleton — extra scrutiny: does the state truly need to be global? Would DI be cleaner?
- Event handlers/callbacks — one event type with one response; for async, evaluate the complete operation, not just what runs before
await.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/cc-routine-and-class-design/SKILL.md
Popularity
- Repository stars
- 117
- Repository forks
- 8
- 7-day trend score
- 24
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 17 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/ryanthedev/code-foundations/cc-routine-and-class-design)