code-quality-principles
npx machina-cli add skill athola/claude-night-market/code-quality-principles --openclawTable of Contents
- KISS (Keep It Simple, Stupid)
- YAGNI (You Aren't Gonna Need It)
- SOLID Principles
- Quick Reference
- When Principles Conflict
- Integration with Code Review
Code Quality Principles
Guidance on KISS, YAGNI, and SOLID principles with language-specific examples.
When To Use
- Improving code readability and maintainability
- Applying SOLID, KISS, YAGNI principles during refactoring
When NOT To Use
- Throwaway scripts or one-time data migrations
- Performance-critical code where readability trades are justified
KISS (Keep It Simple, Stupid)
Principle: Avoid unnecessary complexity. Prefer obvious solutions over clever ones.
Guidelines
| Prefer | Avoid |
|---|---|
| Simple conditionals | Complex regex for simple checks |
| Explicit code | Magic numbers/strings |
| Standard patterns | Clever shortcuts |
| Direct solutions | Over-abstracted layers |
Python Example
# Bad: Overly clever one-liner
users = [u for u in (db.get(id) for id in ids) if u and u.active and not u.banned]
# Good: Clear and readable
users = []
for user_id in ids:
user = db.get(user_id)
if user and user.active and not user.banned:
users.append(user)
Rust Example
// Bad: Unnecessary complexity
fn process(data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
data.iter()
.map(|&b| b.checked_add(1).ok_or("overflow"))
.collect::<Result<Vec<_>, _>>()
.map_err(|e| e.into())
}
// Good: Simple and clear
fn process(data: &[u8]) -> Result<Vec<u8>, &'static str> {
let mut result = Vec::with_capacity(data.len());
for &byte in data {
result.push(byte.checked_add(1).ok_or("overflow")?);
}
Ok(result)
}
YAGNI (You Aren't Gonna Need It)
Principle: Don't implement features until they are actually needed.
Guidelines
| Do | Don't |
|---|---|
| Solve current problem | Build for hypothetical futures |
| Add when 3rd use case appears | Create abstractions for 1 use case |
| Delete dead code | Keep "just in case" code |
| Minimal viable solution | Premature optimization |
Python Example
# Bad: Premature abstraction for one use case
class AbstractDataProcessor:
def process(self, data): ...
def validate(self, data): ...
def transform(self, data): ...
class CSVProcessor(AbstractDataProcessor):
def process(self, data):
return self.transform(self.validate(data))
# Good: Simple function until more cases appear
def process_csv(data: list[str]) -> list[dict]:
return [parse_row(row) for row in data if row.strip()]
TypeScript Example
// Bad: Over-engineered config system
interface ConfigProvider<T> {
get<K extends keyof T>(key: K): T[K];
set<K extends keyof T>(key: K, value: T[K]): void;
watch<K extends keyof T>(key: K, callback: (v: T[K]) => void): void;
}
// Good: Simple config for current needs
const config = {
apiUrl: process.env.API_URL || 'http://localhost:3000',
timeout: 5000,
};
SOLID Principles
Single Responsibility Principle
Each module/class should have one reason to change.
# Bad: Multiple responsibilities
class UserManager:
def create_user(self, data): ...
def send_welcome_email(self, user): ... # Email responsibility
def generate_report(self, users): ... # Reporting responsibility
# Good: Separated responsibilities
class UserRepository:
def create(self, data): ...
class EmailService:
def send_welcome(self, user): ...
class UserReportGenerator:
def generate(self, users): ...
Open/Closed Principle
Open for extension, closed for modification.
# Bad: Requires modification for new types
def calculate_area(shape):
if shape.type == "circle":
return 3.14 * shape.radius ** 2
elif shape.type == "rectangle":
return shape.width * shape.height
# Must modify to add new shapes
# Good: Extensible without modification
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self) -> float: ...
class Circle(Shape):
def __init__(self, radius: float):
self.radius = radius
def area(self) -> float:
return 3.14 * self.radius ** 2
Liskov Substitution Principle
Subtypes must be substitutable for their base types.
# Bad: Violates LSP - Square changes Rectangle behavior
class Rectangle:
def set_width(self, w): self.width = w
def set_height(self, h): self.height = h
class Square(Rectangle): # Breaks when used as Rectangle
def set_width(self, w):
self.width = self.height = w # Unexpected side effect
# Good: Separate types with common interface
class Shape(ABC):
@abstractmethod
def area(self) -> float: ...
class Rectangle(Shape):
def __init__(self, width: float, height: float): ...
class Square(Shape):
def __init__(self, side: float): ...
Interface Segregation Principle
Clients shouldn't depend on interfaces they don't use.
// Bad: Fat interface
interface Worker {
work(): void;
eat(): void;
sleep(): void;
}
// Good: Segregated interfaces
interface Workable {
work(): void;
}
interface Feedable {
eat(): void;
}
// Clients only implement what they need
class Robot implements Workable {
work(): void { /* ... */ }
}
Dependency Inversion Principle
Depend on abstractions, not concretions.
# Bad: Direct dependency on concrete class
class OrderService:
def __init__(self):
self.db = PostgresDatabase() # Tight coupling
# Good: Depend on abstraction
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def save(self, data): ...
class OrderService:
def __init__(self, db: Database):
self.db = db # Injected abstraction
Quick Reference
| Principle | Question to Ask | Red Flag |
|---|---|---|
| KISS | "Is there a simpler way?" | Complex solution for simple problem |
| YAGNI | "Do I need this right now?" | Building for hypothetical use cases |
| SRP | "What's the one reason to change?" | Class doing multiple jobs |
| OCP | "Can I extend without modifying?" | Switch statements for types |
| LSP | "Can subtypes replace base types?" | Overridden methods with side effects |
| ISP | "Does client need all methods?" | Empty method implementations |
| DIP | "Am I depending on abstractions?" | new keyword in business logic |
When Principles Conflict
- KISS vs SOLID: For small projects, KISS wins. Add SOLID patterns as complexity grows.
- YAGNI vs DIP: Don't add abstractions until you have 2+ implementations.
- Readability vs DRY: Prefer slight duplication over wrong abstraction.
Integration with Code Review
When reviewing code, check:
- No unnecessary complexity (KISS)
- No speculative features (YAGNI)
- Each class has single responsibility (SRP)
- No god classes (> 500 lines)
- Dependencies are injected, not created (DIP)
Verification: Run wc -l <file> to check line counts and grep -c "class " <file> to count classes per file.
Source
git clone https://github.com/athola/claude-night-market/blob/master/plugins/conserve/skills/code-quality-principles/SKILL.mdView on GitHub Overview
Provides practical guidance on KISS, YAGNI, and SOLID to keep code simple, avoid over-engineering, and improve maintainability. Through language-specific examples and actionable guidelines, it helps engineers apply clean-code principles during refactoring and code reviews.
How This Skill Works
The skill groups core principles into clear guidelines and contrasts (Prefer/Avoid, Do/Don't) and offers runnable examples in Python, Rust, and TypeScript to illustrate correct and incorrect implementations for clean code practices.
When to Use It
- Improving code readability and maintainability
- Refactoring to apply SOLID, KISS, and YAGNI principles
- Avoiding unnecessary complexity and premature abstractions
- Conducting code reviews to enforce clean-code principles
- Evaluating whether to add abstractions only when a real need appears
Quick Start
- Step 1: Identify areas of unnecessary complexity or premature abstractions in the codebase
- Step 2: Apply KISS and YAGNI to simplify or remove features not currently needed
- Step 3: Refactor toward SOLID guidelines (e.g., SRP) and validate with code reviews
Best Practices
- Prefer simple conditionals and explicit code; avoid clever hacks
- Use explicit, standard patterns over magic numbers/strings
- Apply YAGNI: implement only what is currently needed
- Start with a minimal viable solution and iteratively improve
- Keep responsibilities focused: follow the Single Responsibility Principle and avoid over-abstracted layers
Example Use Cases
- Python KISS: Bad overly clever one-liner vs Good clear and readable loop
- Rust KISS: Bad unnecessary complexity vs Good simple loop
- Python YAGNI: Premature abstraction for one use case vs Simple function until more cases appear
- TypeScript YAGNI: Over-engineered config system vs Simple config for current needs
- SOLID SRP: Bad multi-responsibility class vs Good separation into repository and service components
Frequently Asked Questions
Related Skills
webapp-testing
anthropics/skills
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
coding-assistant
chinkan/RustFox
Help users write, review, and debug code
Governance
smith-horn/product-builder-starter
Enforces engineering standards and code quality policies. Use during code reviews, before commits, when discussing standards or compliance, for quality audits, and when running retrospectives. Trigger phrases include 'run a retro', 'retrospective', 'code review', 'run review', or 'audit standards'.
Worktree Manager
smith-horn/product-builder-starter
Manage git worktrees for parallel development with conflict prevention and wave-aware execution strategy. Use when creating feature branches, starting parallel work sessions, merging worktree PRs, or coordinating multiple Claude sessions.
development-workflow
athola/claude-night-market
detailed development workflow with modular patterns for git, code review, testing, documentation, and deployment
skill-check
olgasafonova/SkillCheck-Free
Validate Claude Code skills against Anthropic guidelines. Use when user says "check skill", "skillcheck", "validate SKILL.md", or asks to find issues in skill definitions. Contains complete validation knowledge.