Clean Code Framework
A disciplined approach to writing code that communicates intent, minimizes surprises, and welcomes change.
When to Use / When Not to Use
| Use |
Skip |
| Code review or PR feedback |
Architectural layer decisions (use clean-architecture) |
| Refactoring legacy code |
Domain modeling (use domain-driven-design) |
| Writing new code that others will maintain |
Performance optimization (profile first) |
| Naming variables, functions, classes |
Infrastructure or deployment config |
Process
- Score the code — Rate 0–10 based on the framework below; state the score explicitly
- Identify smells — List specific violations by category (names, functions, comments, errors, tests)
- Prioritize — Address highest-impact issues first (usually names and function size)
- Refactor — Apply targeted fixes with before/after examples
- Verify — Confirm tests still pass; re-score
Scoring
Goal: 10/10. Rate code 0–10 based on adherence to the principles below.
- 9–10: Names reveal intent, functions small and focused, error handling consistent, tests clean and comprehensive
- 7–8: Mostly clean with minor naming ambiguities or a few long functions
- 5–6: Mixed quality — some good patterns alongside unclear names or duplicated logic
- 3–4: Significant readability issues — long functions, misleading names, poor or missing tests
- 1–2: Code works but is nearly unreadable — magic numbers, cryptic abbreviations, no tests
The Clean Code Framework
1. Meaningful Names
Names should reveal intent, avoid disinformation, and make the code read like prose.
| Context |
Pattern |
Example |
| Variables |
Intention-revealing name |
elapsedTimeInDays not d |
| Booleans |
Predicate phrasing |
isActive, hasPermission, canEdit |
| Functions |
Verb + noun describing action |
calculateMonthlyRevenue() not calc() |
| Classes |
Noun describing responsibility |
InvoiceGenerator not InvoiceManager |
| Constants |
Searchable, all-caps with context |
MAX_RETRY_ATTEMPTS = 3 not 3 inline |
| Collections |
Plural nouns or descriptive phrases |
activeUsers not list or data |
See: references/naming-conventions.md
2. Functions
Functions should be small (4–6 lines ideal), do one thing, and operate at a single level of abstraction.
| Context |
Pattern |
Example |
| Long function |
Extract into named steps |
validateInput(); transformData(); saveRecord(); |
| Flag argument |
Split into two functions |
renderForPrint() and renderForScreen() not render(isPrint) |
| Deep nesting |
Extract inner blocks |
Move nested if/for bodies into named functions |
| Multiple returns |
Guard clauses at top |
Early return for error cases, single happy path |
| Many arguments |
Introduce parameter object |
new DateRange(start, end) not report(start, end, format, locale) |
See: references/functions-and-methods.md
3. Comments and Formatting
A comment is a failure to express yourself in code. Comments should explain why, never what.
| Context |
Pattern |
Example |
| Explaining "what" |
Replace with better name |
Rename // check if eligible to isEligible() |
| Explaining "why" |
Keep as comment |
// RFC 7231 requires this header for proxies |
| Commented-out code |
Delete it |
Trust version control to remember |
| File organization |
Newspaper metaphor |
High-level functions at top, details below |
| Team formatting |
Agree on rules once |
Use automated formatters (Prettier, Black, gofmt) |
See: references/comments-formatting.md
4. Error Handling
Use exceptions rather than return codes, provide context with every exception, and never return or pass null.
| Context |
Pattern |
Example |
| Null returns |
Return empty collection or Optional |
return Collections.emptyList() not return null |
| Error codes |
Replace with exceptions |
throw new InsufficientFundsException(balance, amount) |
| Third-party APIs |
Wrap with adapter |
PortfolioService wraps vendor API, translates exceptions |
| Special cases |
Null Object pattern |
GuestUser with default behavior instead of null checks |
See: references/error-handling.md
5. Unit Testing
Tests are first-class code — clean, readable, maintained with the same discipline as production code.
| Context |
Pattern |
Example |
| Test structure |
Arrange-Act-Assert |
Setup, execute, verify — clearly separated |
| Test naming |
Scenario + expected behavior |
shouldRejectExpiredToken not test1 |
| Flaky tests |
Remove external dependencies |
Mock time, network, file system |
| Test readability |
Domain-specific helpers |
assertThatInvoice(inv).isPaidInFull() |
See: references/testing-principles.md
6. Code Smells and Heuristics
| Context |
Pattern |
Example |
| Duplication |
Extract shared logic |
Common validation → validateEmail() helper |
| Long parameter list |
Introduce parameter object |
SearchCriteria groups related params |
| Feature envy |
Move method to data's class |
order.calculateTotal() not calculator.total(order) |
| Dead code |
Delete it |
Remove unused functions, unreachable branches |
| Magic numbers |
Named constants |
MAX_LOGIN_ATTEMPTS = 5 not bare 5 |
See: references/code-smells.md
Quick Diagnostic
| Question |
If No |
Action |
| Can you understand each function without reading its body? |
Names don't reveal intent |
Rename functions to describe what they do |
| Are all functions under 20 lines? |
Functions do too many things |
Extract sub-operations into named helpers |
| Are there zero commented-out code blocks? |
Dead code creating confusion |
Delete them — version control has history |
| Is error handling separate from business logic? |
Try-catch cluttering main flow |
Extract error handling; use exceptions not return codes |
| Does every class have a single responsibility? |
Classes accumulate unrelated duties |
Split into focused classes with clear names |
| Is there a test for every public method? |
No safety net for changes |
Add tests before making further changes |
| Are magic numbers replaced with named constants? |
Intent hidden behind raw values |
Extract constants with descriptive names |
Output Template
When reviewing code, provide:
- Score (0–10) with justification
- Top 3–5 issues by category
- Before/after code snippets for each fix
- Improved score after fixes applied
What Claude Does / What You Do
| Claude |
You |
| Scores the code and lists specific violations |
Share the code or PR diff |
| Produces before/after refactoring examples |
Confirm business intent behind unclear code |
| Suggests better names with reasoning |
Apply fixes and run tests |
| Identifies test coverage gaps |
Merge after teammate review |
Reference Files
- naming-conventions.md
- functions-and-methods.md
- comments-formatting.md
- error-handling.md
- testing-principles.md
- code-smells.md
Related Skills
develop:clean-architecture — architectural layer structure and dependency rule
develop:domain-driven-design — domain modeling and ubiquitous language
develop:test-master — comprehensive test generation
develop:test-driven-development — test-first workflow
1---2name: clean-code3description: Use when reviewing, refactoring, or writing code that others need to read and maintain — any code that is hard to understand, has grown too long, or whose intent is not immediately clear. Triggers on: "리팩토링", "코드 가독성", "clean code", "code review".4license: MIT5---67# Clean Code Framework89A disciplined approach to writing code that communicates intent, minimizes surprises, and welcomes change.1011## When to Use / When Not to Use1213| Use | Skip |14|-----|------|15| Code review or PR feedback | Architectural layer decisions (use clean-architecture) |16| Refactoring legacy code | Domain modeling (use domain-driven-design) |17| Writing new code that others will maintain | Performance optimization (profile first) |18| Naming variables, functions, classes | Infrastructure or deployment config |1920## Process21221. **Score the code** — Rate 0–10 based on the framework below; state the score explicitly232. **Identify smells** — List specific violations by category (names, functions, comments, errors, tests)243. **Prioritize** — Address highest-impact issues first (usually names and function size)254. **Refactor** — Apply targeted fixes with before/after examples265. **Verify** — Confirm tests still pass; re-score2728## Scoring2930**Goal: 10/10.** Rate code 0–10 based on adherence to the principles below.3132- **9–10:** Names reveal intent, functions small and focused, error handling consistent, tests clean and comprehensive33- **7–8:** Mostly clean with minor naming ambiguities or a few long functions34- **5–6:** Mixed quality — some good patterns alongside unclear names or duplicated logic35- **3–4:** Significant readability issues — long functions, misleading names, poor or missing tests36- **1–2:** Code works but is nearly unreadable — magic numbers, cryptic abbreviations, no tests3738## The Clean Code Framework3940### 1. Meaningful Names4142Names should reveal intent, avoid disinformation, and make the code read like prose.4344| Context | Pattern | Example |45|---------|---------|---------|46| Variables | Intention-revealing name | `elapsedTimeInDays` not `d` |47| Booleans | Predicate phrasing | `isActive`, `hasPermission`, `canEdit` |48| Functions | Verb + noun describing action | `calculateMonthlyRevenue()` not `calc()` |49| Classes | Noun describing responsibility | `InvoiceGenerator` not `InvoiceManager` |50| Constants | Searchable, all-caps with context | `MAX_RETRY_ATTEMPTS = 3` not `3` inline |51| Collections | Plural nouns or descriptive phrases | `activeUsers` not `list` or `data` |5253See: [references/naming-conventions.md](references/naming-conventions.md)5455### 2. Functions5657Functions should be small (4–6 lines ideal), do one thing, and operate at a single level of abstraction.5859| Context | Pattern | Example |60|---------|---------|---------|61| Long function | Extract into named steps | `validateInput(); transformData(); saveRecord();` |62| Flag argument | Split into two functions | `renderForPrint()` and `renderForScreen()` not `render(isPrint)` |63| Deep nesting | Extract inner blocks | Move nested `if`/`for` bodies into named functions |64| Multiple returns | Guard clauses at top | Early return for error cases, single happy path |65| Many arguments | Introduce parameter object | `new DateRange(start, end)` not `report(start, end, format, locale)` |6667See: [references/functions-and-methods.md](references/functions-and-methods.md)6869### 3. Comments and Formatting7071A comment is a failure to express yourself in code. Comments should explain *why*, never *what*.7273| Context | Pattern | Example |74|---------|---------|---------|75| Explaining "what" | Replace with better name | Rename `// check if eligible` to `isEligible()` |76| Explaining "why" | Keep as comment | `// RFC 7231 requires this header for proxies` |77| Commented-out code | Delete it | Trust version control to remember |78| File organization | Newspaper metaphor | High-level functions at top, details below |79| Team formatting | Agree on rules once | Use automated formatters (Prettier, Black, gofmt) |8081See: [references/comments-formatting.md](references/comments-formatting.md)8283### 4. Error Handling8485Use exceptions rather than return codes, provide context with every exception, and never return or pass null.8687| Context | Pattern | Example |88|---------|---------|---------|89| Null returns | Return empty collection or Optional | `return Collections.emptyList()` not `return null` |90| Error codes | Replace with exceptions | `throw new InsufficientFundsException(balance, amount)` |91| Third-party APIs | Wrap with adapter | `PortfolioService` wraps vendor API, translates exceptions |92| Special cases | Null Object pattern | `GuestUser` with default behavior instead of null checks |9394See: [references/error-handling.md](references/error-handling.md)9596### 5. Unit Testing9798Tests are first-class code — clean, readable, maintained with the same discipline as production code.99100| Context | Pattern | Example |101|---------|---------|---------|102| Test structure | Arrange-Act-Assert | Setup, execute, verify — clearly separated |103| Test naming | Scenario + expected behavior | `shouldRejectExpiredToken` not `test1` |104| Flaky tests | Remove external dependencies | Mock time, network, file system |105| Test readability | Domain-specific helpers | `assertThatInvoice(inv).isPaidInFull()` |106107See: [references/testing-principles.md](references/testing-principles.md)108109### 6. Code Smells and Heuristics110111| Context | Pattern | Example |112|---------|---------|---------|113| Duplication | Extract shared logic | Common validation → `validateEmail()` helper |114| Long parameter list | Introduce parameter object | `SearchCriteria` groups related params |115| Feature envy | Move method to data's class | `order.calculateTotal()` not `calculator.total(order)` |116| Dead code | Delete it | Remove unused functions, unreachable branches |117| Magic numbers | Named constants | `MAX_LOGIN_ATTEMPTS = 5` not bare `5` |118119See: [references/code-smells.md](references/code-smells.md)120121## Quick Diagnostic122123| Question | If No | Action |124|----------|-------|--------|125| Can you understand each function without reading its body? | Names don't reveal intent | Rename functions to describe what they do |126| Are all functions under 20 lines? | Functions do too many things | Extract sub-operations into named helpers |127| Are there zero commented-out code blocks? | Dead code creating confusion | Delete them — version control has history |128| Is error handling separate from business logic? | Try-catch cluttering main flow | Extract error handling; use exceptions not return codes |129| Does every class have a single responsibility? | Classes accumulate unrelated duties | Split into focused classes with clear names |130| Is there a test for every public method? | No safety net for changes | Add tests before making further changes |131| Are magic numbers replaced with named constants? | Intent hidden behind raw values | Extract constants with descriptive names |132133## Output Template134135When reviewing code, provide:1361. Score (0–10) with justification1372. Top 3–5 issues by category1383. Before/after code snippets for each fix1394. Improved score after fixes applied140141## What Claude Does / What You Do142143| Claude | You |144|--------|-----|145| Scores the code and lists specific violations | Share the code or PR diff |146| Produces before/after refactoring examples | Confirm business intent behind unclear code |147| Suggests better names with reasoning | Apply fixes and run tests |148| Identifies test coverage gaps | Merge after teammate review |149150## Reference Files151152- [naming-conventions.md](references/naming-conventions.md)153- [functions-and-methods.md](references/functions-and-methods.md)154- [comments-formatting.md](references/comments-formatting.md)155- [error-handling.md](references/error-handling.md)156- [testing-principles.md](references/testing-principles.md)157- [code-smells.md](references/code-smells.md)158159## Related Skills160161- `develop:clean-architecture` — architectural layer structure and dependency rule162- `develop:domain-driven-design` — domain modeling and ubiquitous language163- `develop:test-master` — comprehensive test generation164- `develop:test-driven-development` — test-first workflow