重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
code-quality-principles by athola/claude-night-market
npx skills add https://github.com/athola/claude-night-market --skill code-quality-principles关于 KISS、YAGNI 和 SOLID 原则的指南,包含特定语言的示例。
原则:避免不必要的复杂性。优先选择显而易见的解决方案,而不是巧妙的方案。
| 优先选择 | 避免 |
|---|---|
| 简单的条件判断 | 用复杂正则表达式进行简单检查 |
| 显式代码 | 魔法数字/字符串 |
| 标准模式 | 巧妙的捷径 |
| 直接解决方案 | 过度抽象的层次 |
# 不好:过于巧妙的单行代码
users = [u for u in (db.get(id) for id in ids) if u and u.active and not u.banned]
# 好:清晰且可读
users = []
for user_id in ids:
user = db.get(user_id)
if user and user.active and not user.banned:
users.append(user)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
// 不好:不必要的复杂性
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())
}
// 好:简单明了
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)
}
原则:不要实现实际不需要的功能。
| 做 | 不做 |
|---|---|
| 解决当前问题 | 为假想的未来构建 |
| 当第 3 个用例出现时再添加 | 为 1 个用例创建抽象 |
| 删除死代码 | 保留“以防万一”的代码 |
| 最小可行解决方案 | 过早优化 |
# 不好:为一个用例过早抽象
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))
# 好:在更多用例出现前使用简单函数
def process_csv(data: list[str]) -> list[dict]:
return [parse_row(row) for row in data if row.strip()]
// 不好:过度设计的配置系统
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;
}
// 好:满足当前需求的简单配置
const config = {
apiUrl: process.env.API_URL || 'http://localhost:3000',
timeout: 5000,
};
每个模块/类应该只有一个变更的理由。
# 不好:多个职责
class UserManager:
def create_user(self, data): ...
def send_welcome_email(self, user): ... # 邮件职责
def generate_report(self, users): ... # 报告职责
# 好:职责分离
class UserRepository:
def create(self, data): ...
class EmailService:
def send_welcome(self, user): ...
class UserReportGenerator:
def generate(self, users): ...
对扩展开放,对修改关闭。
# 不好:添加新类型需要修改
def calculate_area(shape):
if shape.type == "circle":
return 3.14 * shape.radius ** 2
elif shape.type == "rectangle":
return shape.width * shape.height
# 必须修改才能添加新形状
# 好:无需修改即可扩展
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
子类型必须可以替换其基类型。
# 不好:违反 LSP - Square 改变了 Rectangle 的行为
class Rectangle:
def set_width(self, w): self.width = w
def set_height(self, h): self.height = h
class Square(Rectangle): # 当作为 Rectangle 使用时出错
def set_width(self, w):
self.width = self.height = w # 意外的副作用
# 好:具有公共接口的独立类型
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 Worker {
work(): void;
eat(): void;
sleep(): void;
}
// 好:分离的接口
interface Workable {
work(): void;
}
interface Feedable {
eat(): void;
}
// 客户端只实现它们需要的部分
class Robot implements Workable {
work(): void { /* ... */ }
}
依赖抽象,而不是具体实现。
# 不好:直接依赖具体类
class OrderService:
def __init__(self):
self.db = PostgresDatabase() # 紧耦合
# 好:依赖抽象
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def save(self, data): ...
class OrderService:
def __init__(self, db: Database):
self.db = db # 注入的抽象
| 原则 | 要问的问题 | 危险信号 |
|---|---|---|
| KISS | "有更简单的方法吗?" | 用复杂方案解决简单问题 |
| YAGNI | "我现在就需要这个吗?" | 为假想用例构建 |
| SRP | "变更的唯一理由是什么?" | 类承担多个工作 |
| OCP | "我能否在不修改的情况下扩展?" | 用于类型判断的 switch 语句 |
| LSP | "子类型能否替换基类型?" | 具有副作用的重写方法 |
| ISP | "客户端需要所有方法吗?" | 空方法实现 |
| DIP | "我是否依赖抽象?" | 业务逻辑中的 new 关键字 |
审查代码时,检查:
验证: 运行 wc -l <file> 检查行数,运行 grep -c "class " <file> 统计每个文件的类数量。
每周安装数
52
代码仓库
GitHub 星标数
211
首次出现
Jan 22, 2026
安全审计
已安装于
opencode44
codex43
gemini-cli41
claude-code38
github-copilot35
cursor33
Guidance on KISS, YAGNI, and SOLID principles with language-specific examples.
Principle : Avoid unnecessary complexity. Prefer obvious solutions over clever ones.
| Prefer | Avoid |
|---|---|
| Simple conditionals | Complex regex for simple checks |
| Explicit code | Magic numbers/strings |
| Standard patterns | Clever shortcuts |
| Direct solutions | Over-abstracted layers |
# 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)
// 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)
}
Principle : Don't implement features until they are actually needed.
| 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 |
# 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()]
// 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,
};
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 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
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): ...
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 { /* ... */ }
}
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
| 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 reviewing code, check:
Verification: Run wc -l <file> to check line counts and grep -c "class " <file> to count classes per file.
Weekly Installs
52
Repository
GitHub Stars
211
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode44
codex43
gemini-cli41
claude-code38
github-copilot35
cursor33
CodeQL代码扫描配置指南 - GitHub Actions工作流与CLI本地运行教程
854 周安装