匠心码道丨01 编写优质代码的十大黄金法则
代码质量的优劣直接影响着项目的可维护性和团队的开发效率。一个经验丰富的开发者不仅要能实现功能,更要善于编写清晰易懂、结构合理的代码。本文将介绍 10 条帮助你编写清晰、易维护且可扩展代码的重要规则。
规则
1. 使用有意义的变量和函数名称
变量、函数和类的命名应该具有描述性和意义。你的代码应该能够清晰地表达其意图,而无需额外的注释来解释。
反面示例: 1
2
3
4let a = 10;
const d = new Date();
const res = await api.get();
const arr = users.filter(u => u.a === true);
正面示例: 1
2
3
4let maxRetries = 10;
const currentDate = new Date();
const userResponse = await api.getUserProfile();
const activeUsers = users.filter(user => user.isActive === true);
有意义的命名能讲述代码的故事。读者应该能够仅通过名称就理解变量或函数的用途。
💡实践建议:
- 使用动词前缀命名函数:
getUserProfile()
、validateInput()
、calculateTotal()
- 使用名词命名变量:
userCount
、activeUsers
、orderStatus
- 布尔值使用 is/has/should
等前缀:
isValid
、hasPermission
、shouldUpdate
2. 保持函数简短且专注
函数应该保持简短,并且只做一件事。函数承担的责任越多,测试、调试和理解起来就越困难。
反面示例: 1
2
3def process_order(order):
# 多个责任:验证、定价、折扣、配送等
pass
正面示例: 1
2
3
4
5
6
7
8def validate_order(order):
pass
def calculate_total(order):
pass
def apply_discount(order):
pass
每个函数应该只有一个责任。如果你需要用"和"来描述函数的功能,那么这个函数可能做得太多了。
💡 最佳实践:
- 函数建议保持在 20-30 行以内
- 如果超过 50 行,应该考虑拆分
- 一个函数最好不要超过 3 个参数
3. 避免深层嵌套
深层嵌套的循环和条件语句会使代码难以理解。通过使用提前返回、函数拆分或将大问题分解为小问题来使代码扁平化。
反面示例: 1
2
3
4
5
6
7if (user != null) {
if (user.isActive()) {
if (order != null) {
processOrder(order);
}
}
}
正面示例: 1
2
3if (user == null || !user.isActive()) return;
if (order == null) return;
processOrder(order);
提前返回可以减少读者的认知负担,使代码更简单、更容易理解。
4. 明智地使用注释
注释不应该解释代码做了什么;代码本身应该是自解释的。只在必要时使用注释来解释复杂逻辑背后的"原因",而不是"是什么"。
反面示例: 1
2// 设置用户状态为激活
$user->isActive = true;
正面示例: 1
2// 登录成功后将用户标记为激活状态
$user->isActive = true;
注释应该增加价值,解释特定实现背后的原因或解释复杂的业务逻辑。
5. 保持一致的格式
一致的代码格式使代码更容易阅读和导航。在项目中使用统一的缩进、间距和对齐方式。
反面示例: 1
function calculate(a,b){return a+b;}
正面示例: 1
2
3function calculate(a, b) {
return a + b;
}
许多团队使用 Prettier 或 ESLint 等工具来自动格式化并强制执行代码风格规则。
6. 不要重复自己(DRY 原则)
代码重复会导致不一致、bug 和不必要的复杂性。应用 DRY 原则可以保持代码库精简,更易于维护。
反面示例: 1
2
3
4
5
6if ($userType == "admin") {
// 复杂逻辑
}
if ($userType == "superadmin") {
// 相同的复杂逻辑
}
正面示例: 1
2
3if (userIsAdmin($userType)) {
// 复杂逻辑
}
通过将共同逻辑抽象到函数、类或工具中来避免代码重复。
7. 单一责任原则(SRP)
每个类和函数应该只有一个改变的理由。遵循单一责任原则使代码模块化,更容易重构。
反面示例: 1
2
3
4
5class User {
void register();
void login();
void sendEmail();
}
正面示例: 1
2
3
4
5
6
7
8class User {
void register();
void login();
}
class EmailService {
void sendEmail();
}
承担太多责任的类更难维护。SRP 使代码更模块化,更容易测试。
8. 避免魔法数字和字符串
魔法数字(或字符串)是没有上下文或解释的硬编码值。使用常量或枚举代替,这样可以增加代码的清晰度。
反面示例: 1
2discount = 0.05
if user.role == "admin":
正面示例: 1
2
3
4DISCOUNT_RATE = 0.05
ADMIN_ROLE = "admin"
discount = DISCOUNT_RATE
if user.role == ADMIN_ROLE:
常量为数字或字符串提供了含义,使代码更容易理解。
9. 编写测试
单元测试和集成测试确保你的代码按预期工作,并且在进行更改时不会出错。编写测试使代码更可靠,长期更易于维护。
反面示例: 1
2
3
4// 这个方法没有测试
public void processOrder(Order order) {
// 逻辑
}
正面示例: 1
2
3
4
5@Test
public void testProcessOrder() {
Order order = new Order();
// 断言
}
测试应该成为你工作流程的一部分,确保代码无 BUG 且稳定。
10. 保持简单(KISS 原则)
KISS(Keep It Simple, Stupid)原则提醒我们简单是关键。复杂的解决方案会导致混淆,更难维护。在面对决策时,选择最简单、最直接的方案来满足需求。
反面示例: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 过度复杂的购物车商品总价计算
function calculateTotal(items) {
let total = 0;
let discount = 0;
// 复杂的折扣计算逻辑
items.forEach(item => {
if (item.category === 'electronics') {
if (item.price > 1000) {
discount += item.price * 0.1;
} else if (item.price > 500) {
discount += item.price * 0.05;
}
} else if (item.category === 'books') {
if (item.quantity > 3) {
discount += item.price * item.quantity * 0.15;
}
}
total += item.price * item.quantity;
});
return total - discount;
}
正面示例: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 将复杂逻辑拆分成小函数
function calculateDiscount(item) {
if (item.category === 'electronics') {
return item.price > 1000 ? 0.1 : (item.price > 500 ? 0.05 : 0);
}
if (item.category === 'books' && item.quantity > 3) {
return 0.15;
}
return 0;
}
function calculateTotal(items) {
return items.reduce((total, item) => {
const discount = calculateDiscount(item);
const itemTotal = item.price * item.quantity;
return total + itemTotal * (1 - discount);
}, 0);
}
💡 最佳实践:
- 将复杂逻辑拆分成小的、容易理解的函数
- 避免在一个函数中处理过多的条件判断
- 使用清晰的命名来表达意图
- 保持函数的单一职责
总结
干净的代码对于可维护性、可读性和协作至关重要。遵循这 10 条规则——使用有意义的命名、保持函数简短、避免魔法数字、编写测试等,将会带来更健壮、更易理解和更易扩展的代码库。编写代码不仅仅是要让它能工作,更要让其他人(包括未来的你)能够轻松理解和扩展。
代码审查清单
在提交代码前,可以使用以下清单进行自查: