AgentSkillsCN

clean-code-principles

遵循 SOLID、DRY、KISS、YAGNI、Clean Code 以及软件工匠精神的规范性编码标准。适用于所有代码生成、重构与代码审查任务。这些规则并非建议,而是强制性要求。适用于任何编程语言。

SKILL.md
--- frontmatter
name: clean-code-principles
description: Prescriptive coding standards enforcing SOLID, DRY, KISS, YAGNI, Clean Code, and software craftsmanship principles. Apply to ALL code generation, refactoring, and code review tasks. These rules are mandatory, not suggestions. Use for any programming language.

Clean Code Principles

These principles are mandatory for all code produced. Apply them automatically without exception.


SOLID Principles

S — Single Responsibility Principle (SRP)

Every module/class/function does ONE thing.

  • If you need "and" to describe what it does, split it
  • One reason to change per unit
  • Extract until you can't extract anymore
code
❌ getUserAndSendEmail()
✅ getUser() + sendEmail()

O — Open/Closed Principle (OCP)

Open for extension, closed for modification.

  • Use abstractions (interfaces, base classes, higher-order functions)
  • Add new behavior by adding code, not changing existing code
  • Prefer composition over conditionals
code
❌ if (type === 'A') {...} else if (type === 'B') {...}
✅ handlers[type].process()

L — Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their base types.

  • Don't override methods to throw "not implemented"
  • Don't strengthen preconditions or weaken postconditions
  • If it looks like a duck but needs batteries, wrong abstraction

I — Interface Segregation Principle (ISP)

No client should depend on methods it doesn't use.

  • Many small interfaces > one large interface
  • Split fat interfaces into focused ones
  • Clients only know what they need

D — Dependency Inversion Principle (DIP)

Depend on abstractions, not concretions.

  • High-level modules don't import low-level modules directly
  • Both depend on abstractions
  • Inject dependencies, don't instantiate them

Core Principles

DRY — Don't Repeat Yourself

Every piece of knowledge has ONE authoritative representation.

  • If you copy-paste, extract
  • Rule of three: duplicated twice = refactor
  • But: avoid premature abstraction (see YAGNI)

KISS — Keep It Simple, Stupid

Simplest solution that works.

  • No clever tricks
  • Readable > clever
  • If a junior can't understand it, simplify

YAGNI — You Aren't Gonna Need It

Don't build for hypothetical futures.

  • No "just in case" code
  • No premature optimization
  • No speculative generality
  • Build for today's requirements only

Clean Code Standards

Naming

  • Intention-revealing: name describes purpose without comments
  • Pronounceable: can discuss verbally
  • Searchable: avoid single letters except loop indices
  • No encodings: no Hungarian notation, no type prefixes
  • Verb for functions: calculateTotal(), isValid(), hasPermission()
  • Noun for classes/variables: User, orderItems, totalPrice

Functions

  • Small: 5-20 lines ideal, max ~30
  • Do one thing: SRP at function level
  • One level of abstraction: don't mix high and low level
  • Max 3 parameters: more = use object/struct
  • No side effects: or name them explicitly (saveAndNotify)
  • Command-Query Separation: either do something OR return something, not both

Comments

  • Code should be self-documenting: if you need a comment, first try renaming
  • Only comment WHY, never WHAT: code shows what, comments explain non-obvious reasoning
  • No commented-out code: delete it, git remembers
  • No noise comments: // increment i → delete

Error Handling

  • Fail fast: validate early, reject invalid state immediately
  • Use exceptions for exceptional cases: not for flow control
  • Provide context: error messages should explain what happened and ideally how to fix
  • Don't return null: use Optional/Maybe, empty collections, or throw
  • Don't pass null: same reasoning

Structure

  • Vertical proximity: related code stays together
  • Newspaper metaphor: high-level at top, details below
  • One concept per file: don't hide multiple classes/modules
  • Consistent formatting: follow language conventions

Design Heuristics

Composition Over Inheritance

  • Prefer "has-a" over "is-a"
  • Inheritance creates tight coupling
  • Use inheritance only for true "is-a" relationships

Law of Demeter (Minimal Knowledge)

Only talk to:

  • Your own methods
  • Objects you created
  • Objects passed as parameters
  • Direct component objects
code
❌ user.getAddress().getCity().getName()
✅ user.getCityName()

Fail Fast

  • Validate inputs at boundaries
  • Throw early on invalid state
  • Don't let bad data propagate

Separation of Concerns

  • UI logic ≠ business logic ≠ data access
  • Each layer has one job
  • Changes in one layer don't ripple to others

Immutability Where Possible

  • Prefer const/final/readonly
  • Return new objects instead of mutating
  • Immutable = thread-safe, predictable, debuggable

Code Smells to Eliminate

Always refactor these:

  • Long method: extract smaller methods
  • Large class: split by responsibility
  • Long parameter list: introduce parameter object
  • Divergent change: class changes for multiple reasons → split
  • Shotgun surgery: one change affects many classes → consolidate
  • Feature envy: method uses another class more than its own → move it
  • Data clumps: same data groups appear together → create class
  • Primitive obsession: overuse of primitives → create value objects
  • Switch statements: often violate OCP → use polymorphism
  • Parallel inheritance: subclass A requires subclass B → merge hierarchies
  • Lazy class: does too little → inline or merge
  • Speculative generality: unused abstraction → delete
  • Temporary field: sometimes-null fields → extract class
  • Message chains: a.b().c().d() → Law of Demeter violation
  • Middle man: class delegates everything → remove
  • Inappropriate intimacy: classes too coupled → separate or merge
  • Comments explaining bad code: refactor instead

Pre-Commit Checklist

Before considering code complete:

  1. ☐ Each function does ONE thing
  2. ☐ Names are clear and intention-revealing
  3. ☐ No magic numbers/strings (use constants)
  4. ☐ No duplication
  5. ☐ Error cases handled
  6. ☐ No commented-out code
  7. ☐ Functions ≤ 30 lines
  8. ☐ Max 3 parameters per function
  9. ☐ No deep nesting (max 2-3 levels)
  10. ☐ Dependencies injected, not created
  11. ☐ Would a teammate understand this immediately?

Application

When writing or reviewing code:

  1. Apply these principles automatically
  2. If trade-offs exist, prefer: Readability > Cleverness > Performance (unless perf is critical)
  3. When refactoring, fix ONE smell at a time
  4. Leave code cleaner than you found it (Boy Scout Rule)