mcpField
C
code-quality-principles

code-quality-principles

github.com/athola开发343175 次安装1 天前更新
代码仓库

关于 code-quality-principles

面向开发者的编码技能,通过原则说明和 Python、Rust、TypeScript 示例讲解 KISS、YAGNI 与 SOLID,适用于重构中的可读性和可维护性改进。

主要功能

  1. 01KISS、YAGNI 与 SOLID 指引
  2. 02按语言提供代码示例
  3. 03代码审查检查清单
  4. 04原则冲突处理建议

适用场景

  1. 01重构以提升可读性和可维护性
  2. 02审查代码是否存在不必要的复杂性
  3. 03权衡简洁方案与抽象设计

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/athola/claude-night-market --skill code-quality-principles

安装后在 Claude Code 中输入/code-quality-principles确认已加载。

详细介绍

代码质量原则

介绍 KISS、YAGNI 和 SOLID 原则,并提供特定语言的示例。

适用场景

  • 提高代码的可读性和可维护性
  • 重构期间应用 SOLID、KISS 和 YAGNI 原则

不适用场景

  • 一次性脚本或仅运行一次的数据迁移
  • 性能关键型代码,且有理由牺牲可读性

KISS(Keep It Simple, Stupid)

原则:避免不必要的复杂性。优先选择直观的解决方案,而不是巧妙的方案。

指南
优先选择避免
简单的条件判断用复杂正则表达式处理简单检查
明确的代码魔法数字/字符串
标准模式巧妙的捷径
直接的解决方案过度抽象的层次
Python 示例
# 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 示例
// 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)

原则:在功能真正需要之前,不要实现它。

指南
要做不要做
解决当前问题为假想的未来做准备
出现第 3 个使用场景时再添加为 1 个使用场景创建抽象
删除无用代码保留“以防万一”的代码
提供最小可行解决方案过早优化
Python 示例
# 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 示例
// 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 原则

单一职责原则

每个模块/类都应该只有一个变更理由。

# 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): ...
开闭原则

对扩展开放,对修改关闭。

# 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
里氏替换原则

子类型必须能够替换其基类型。

# 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): ...
接口隔离原则

客户端不应依赖它们不会使用的接口。

// 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 { /* ... */ }
}
依赖倒置原则

依赖抽象,而不是具体实现。

# 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

快速参考

原则要问的问题警示信号
KISS“有没有更简单的方法?”用复杂方案解决简单问题
YAGNI“我现在需要这个吗?”为假想的使用场景构建功能
SRP“变更的唯一理由是什么?”类承担多项职责
OCP“能否在不修改的情况下扩展?”针对类型的 switch 语句
LSP“子类型能否替换基类型?”重写的方法带有副作用
ISP“客户端需要所有方法吗?”空方法实现
DIP“我依赖的是抽象吗?”业务逻辑中使用 new 关键字

原则冲突时的处理

  1. KISS 与 SOLID:对于小型项目,优先遵循 KISS。随着复杂性增加,再加入 SOLID 模式。
  2. YAGNI 与 DIP:在有 2 个或更多实现之前,不要添加抽象。
  3. 可读性与 DRY:宁可略微重复,也不要采用错误的抽象。

与代码审查的结合

审查代码时,请检查:

  • 没有不必要的复杂性(KISS)
  • 没有推测性功能(YAGNI)
  • 每个类都只有单一职责(SRP)
  • 没有上帝类(> 500 行)
  • 依赖通过注入提供,而不是自行创建(DIP)

**验证:**运行 wc -l <file> 检查行数,并运行 rg -c "class " <file>(或 grep -c "class " <file>)统计每个文件中的类数量。

相关技能

  • imbue:karpathy-principles - “简洁优先”原则将 KISS、YAGNI 和 SOLID 融合为四项原则的综合体系,源自 Karpathy 对 LLM 编码陷阱的观察
  • 完整的关卡与技能联邦图请参阅 docs/quality-gates.md#skill-level-quality-gate-composition

退出标准

  • 每项拟议的代码更改都已根据集成审查清单检查:没有不必要的复杂性(KISS)、没有推测性功能(YAGNI)、每个类仅承担一项职责(SRP)、没有超过 500 行的巨型类、依赖通过注入而非创建(DIP)
  • 当 KISS 与 SOLID 冲突时,已记录解决方式:小型项目优先采用 KISS,随着复杂性增加再应用 SOLID 模式。明确说明选择,不得默默处理
  • 对任何已修改文件运行 wc -l <file>;如果文件超过 500 行(巨型类阈值),则记录结果
  • 除非作为测试的模拟边界,否则不引入只有一个实现者的新抽象

评论

支持 Markdown