1. DRY 原则(Don’t Repeat Yourself)
核心思想:避免重复代码或逻辑,相同的功能应通过抽象和复用来实现。
目标:减少维护成本,提高代码一致性,降低修改遗漏的风险。
示例
场景:多个模块需要验证用户邮箱格式。
违反 DRY 的代码:
// 模块A
function checkEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
// 模块B
function validateUser(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // 重复的正则表达式
if (!regex.test(email)) throw new Error("Invalid email");
}
遵循 DRY 的改进:
// 公共工具类 utils.js
export const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// 模块A
import { emailRegex } from './utils';
function checkEmail(email) {
return emailRegex.test(email);
}
// 模块B
import { emailRegex } from './utils';
function validateUser(email) {
if (!emailRegex.test(email)) throw new Error("Invalid email");
}
扩展场景:
- 配置重复(如数据库连接参数)应抽离为配置文件。
- 文档重复(如接口说明)应通过自动化工具生成。
2. SOLID 原则
面向对象设计的五大核心原则,提升代码的可维护性和扩展性。
S: 单一职责原则(SRP)
定义:一个类只应有一个职责。
示例:
// 违反 SRP:既管理订单又处理支付
class OrderProcessor {
void createOrder() { ... }
void processPayment() { ... }
}
// 改进:拆分职责
class OrderService { void createOrder() { ... } }
class PaymentService { void processPayment() { ... } }
O: 开放封闭原则(OCP)
定义:通过扩展(如继承、接口)添加新功能,而非修改现有代码。
示例:
# 支持多种日志存储方式(文件、数据库)
class Logger:
def log(self, message): pass
class FileLogger(Logger):
def log(self, message): ... # 写入文件
class DatabaseLogger(Logger):
def log(self, message): ... # 写入数据库
L: 里氏替换原则(LSP)
定义:子类必须能替换父类且不破坏逻辑。
反例:
class Rectangle {
int width, height;
void setWidth(int w) { width = w; }
}
class Square extends Rectangle {
void setWidth(int w) {
width = w;
height = w; // 违反 LSP,修改了父类行为
}
}
I: 接口隔离原则(ISP)
定义:避免臃肿的接口,按需拆分。
示例:
// 错误:多功能接口
interface SmartDevice {
call(): void;
takePhoto(): void;
playMusic(): void;
}
// 正确:按功能拆分
interface Phone { call(): void; }
interface Camera { takePhoto(): void; }
interface MusicPlayer { playMusic(): void; }
D: 依赖倒置原则(DIP)
定义:依赖抽象(接口/抽象类),而非具体实现。
示例:
// 高层模块直接依赖具体数据库(违反 DIP)
class ReportService {
private MySQLDatabase db = new MySQLDatabase();
}
// 改进:依赖抽象
interface Database { void save(); }
class MySQLDatabase implements Database { ... }
class ReportService {
private Database db;
ReportService(Database db) { this.db = db; } // 依赖注入
}
3. KISS 原则(Keep It Simple, Stupid)
核心思想:设计应简单直接,避免不必要的复杂性。
目标:降低理解成本,提升可维护性。
示例
场景:实现一个计算数组平均值的函数。
过度设计:
def calculate_average(arr):
if not isinstance(arr, list):
raise TypeError("Input must be a list")
if len(arr) == 0:
raise ValueError("Array cannot be empty")
total = 0
for num in arr:
if not isinstance(num, (int, float)):
raise TypeError("Elements must be numeric")
total += num
return total / len(arr)
遵循 KISS 的简化:
def calculate_average(arr):
return sum(arr) / len(arr) if arr else 0
典型应用场景:
- 避免过度使用设计模式(如为简单 CRUD 引入复杂分层)。
- 优先选择直接的语言特性(如用
Python
列表推导代替显式循环)。
总结
原则 | 核心思想 | 适用场景 |
---|---|---|
DRY | 消除重复逻辑,抽象复用 | 代码、配置、文档的重复 |
SOLID | 通过模块化、抽象提高扩展性 | 面向对象系统设计 |
KISS | 用最简单的方式解决问题 | 需求明确且无过度扩展预期的场景 |
三者关系:
- DRY 和 SOLID 共同减少代码冗余和耦合,提升可维护性。
- KISS 是设计决策的“刹车”,防止过度应用其他原则导致复杂化。