|
| 1 | +# Clean Code Principles |
| 2 | + |
| 3 | +A comprehensive guide to writing clean, maintainable, and readable code based on Robert C. Martin's "Clean Code" principles. These rules focus on creating code that clearly expresses intent, is easy to understand, modify, and maintain over time. |
| 4 | + |
| 5 | +## Context |
| 6 | + |
| 7 | +Provide guidelines for writing code that prioritizes readability, simplicity, and maintainability over cleverness or optimization. |
| 8 | + |
| 9 | +*Applies to:* All software development projects, code reviews, refactoring efforts |
| 10 | +*Level:* Tactical/Operational - direct application in daily coding practices |
| 11 | +*Audience:* All developers, from junior to senior levels |
| 12 | + |
| 13 | +## Core Principles |
| 14 | + |
| 15 | +1. *Clarity over Cleverness:* Code should be written to be read and understood by humans first, machines second |
| 16 | +2. *Express Intent:* Names, functions, and structure should clearly communicate what the code does and why |
| 17 | +3. *Simplicity:* Prefer simple, straightforward solutions over complex, over-engineered ones |
| 18 | +4. *Single Responsibility:* Each unit of code should have one clear purpose and reason to change |
| 19 | +5. *Leave it Better:* Always improve code when you touch it, following the Boy Scout Rule |
| 20 | + |
| 21 | +## Rules |
| 22 | + |
| 23 | +### Must Have (Critical) |
| 24 | + |
| 25 | +- *RULE-001:* Use meaningful, pronounceable names for variables, functions, classes, and modules |
| 26 | +- *RULE-002:* Functions must be small (ideally <20 lines) and do one thing well |
| 27 | +- *RULE-003:* Eliminate code duplication - follow the DRY principle strictly |
| 28 | +- *RULE-004:* Remove commented-out code and dead code before committing |
| 29 | +- *RULE-005:* Use consistent formatting and indentation throughout the codebase |
| 30 | + |
| 31 | +### Should Have (Important) |
| 32 | + |
| 33 | +- *RULE-101:* Functions should have no more than 3 parameters; use objects for more complex parameter sets |
| 34 | +- *RULE-102:* Avoid deep nesting (>3 levels) - extract methods or use early returns |
| 35 | +- *RULE-103:* Write self-documenting code that reduces need for comments |
| 36 | +- *RULE-104:* Use intention-revealing names rather than mental mapping (avoid single-letter variables except for short loops) |
| 37 | +- *RULE-105:* Keep classes small and focused on a single responsibility |
| 38 | + |
| 39 | +### Could Have (Preferred) |
| 40 | + |
| 41 | +- *RULE-201:* Prefer composition over inheritance |
| 42 | +- *RULE-202:* Use descriptive error messages and proper exception handling |
| 43 | +- *RULE-203:* Order functions by level of abstraction (high-level first, details later) |
| 44 | +- *RULE-204:* Minimize dependencies between modules and classes |
| 45 | +- *RULE-205:* Use consistent verb/noun naming conventions (getUser, calculateTotal, isValid) |
| 46 | + |
| 47 | +## Patterns & Anti-Patterns |
| 48 | + |
| 49 | +### ✅ Do This |
| 50 | + |
| 51 | +```javascript |
| 52 | +function calculateMonthlyPayment(principal, interestRate, termInYears) { |
| 53 | + const monthlyRate = interestRate / 12; |
| 54 | + const numberOfPayments = termInYears * 12; |
| 55 | + |
| 56 | + return (principal * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -numberOfPayments)); |
| 57 | +} |
| 58 | + |
| 59 | +const userAccount = { |
| 60 | + id: userId, |
| 61 | + email: userEmail, |
| 62 | + isActive: true |
| 63 | +}; |
| 64 | +``` |
| 65 | + |
| 66 | +### ❌ Don't Do This |
| 67 | + |
| 68 | +```javascript |
| 69 | +function calc(p, r, t) { |
| 70 | + // Calculate monthly payment |
| 71 | + let mr = r / 12; |
| 72 | + let n = t * 12; |
| 73 | + return (p * mr) / (1 - Math.pow(1 + mr, -n)); |
| 74 | +} |
| 75 | + |
| 76 | +// TODO: fix this later |
| 77 | +// const oldUserData = getUser(id); |
| 78 | +const u = { id: uid, e: ue, a: true }; |
| 79 | +``` |
| 80 | + |
| 81 | +## Decision Framework |
| 82 | + |
| 83 | +*When rules conflict:* |
| 84 | +1. Prioritize readability and maintainability over performance optimizations |
| 85 | +2. Choose the solution that makes the code's intent most clear |
| 86 | +3. Consider the team's collective understanding and skill level |
| 87 | + |
| 88 | +*When facing edge cases:* |
| 89 | +- Ask "Would a new team member understand this code in 6 months?" |
| 90 | +- Prefer explicit over implicit behavior |
| 91 | +- When in doubt, err on the side of being more verbose and clear |
| 92 | + |
| 93 | +## Exceptions & Waivers |
| 94 | + |
| 95 | +*Valid reasons for exceptions:* |
| 96 | +- Performance-critical code paths with demonstrated bottlenecks (document trade-offs) |
| 97 | +- Legacy system integration requiring specific patterns (temporary, with migration plan) |
| 98 | +- Third-party API constraints that force specific implementations |
| 99 | + |
| 100 | +*Process for exceptions:* |
| 101 | +1. Document the exception, rationale, and performance/business justification |
| 102 | +2. Add technical debt tracking item for future refactoring |
| 103 | +3. Review exceptions quarterly to assess if constraints still apply |
| 104 | + |
| 105 | +## Quality Gates |
| 106 | + |
| 107 | +- *Automated checks:* Linting rules for naming conventions, function length, complexity metrics |
| 108 | +- *Code review focus:* Readability, naming clarity, function size, duplication elimination |
| 109 | +- *Testing requirements:* Unit tests must be as clean and readable as production code |
| 110 | + |
| 111 | +## References |
| 112 | + |
| 113 | +- [Clean Code by Robert C. Martin](https://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) |
| 114 | +- [Refactoring by Martin Fowler](https://refactoring.com/) |
| 115 | +- [The Pragmatic Programmer](https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/) |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +## TL;DR |
| 120 | + |
| 121 | +*Key Principles:* |
| 122 | +- Write code for humans to read, not just machines to execute |
| 123 | +- Use clear, descriptive names that express intent without requiring comments |
| 124 | +- Keep functions small, focused, and doing only one thing well |
| 125 | + |
| 126 | +*Critical Rules:* |
| 127 | +- Must use meaningful names for all variables, functions, and classes |
| 128 | +- Must keep functions under 20 lines and eliminate all code duplication |
| 129 | +- Must remove dead code and maintain consistent formatting |
| 130 | + |
| 131 | +*Quick Decision Guide:* |
| 132 | +When in doubt: Choose the option that makes the code's intent most obvious to a future reader. |
0 commit comments