刚工作的时候,我一直以为:
高级工程师写代码快,是因为他们更聪明。
后来参与的项目越来越多,我发现事实并非如此。
很多资深工程师写代码时,并没有使用什么复杂算法,也没有炫技式设计模式。
相反,他们的代码往往有一个共同特点:
简单、清晰、容易维护。
这些代码习惯单独看都不复杂,但组合起来之后,会让整个项目的质量提升一个层次。
今天分享我从高级工程师身上学到的 7 个编码模式。
这些技巧没有语言限制,不过文中的示例主要使用 Go 实现。
1. 用早返回(Early Return)减少嵌套
新手代码经常长这样:
go
func CreateUser(name string) error {
if name != "" {
if len(name) <= 20 {
fmt.Println("create user")
return nil
} else {
return errors.New("name too long")
}
} else {
return errors.New("name empty")
}
}
逻辑本身没问题。
但随着条件增加,代码会越来越向右偏移。
高级工程师通常这样写:
go
func CreateUser(name string) error {
if name == "" {
return errors.New("name empty")
}
if len(name) > 20 {
return errors.New("name too long")
}
fmt.Println("create user")
return nil
}
好处非常明显:
- 减少嵌套
- 更容易阅读
- 错误路径一眼可见
Go 官方标准库其实大量采用这种写法。
例如:
go
if err != nil {
return err
}
就是最经典的 Early Return。
高级工程师很知道阅读代码远比写代码的成本更高,他们写代码时,会优先考虑他人在高压场景下理解代码的难度。
但是也需要注意的是多层嵌套也有其资深优势:有时嵌套结构能直观体现真实的层级关系;解析器、树遍历或是复杂业务流程,本身也需要嵌套逻辑。这条编码原则并非 “绝对禁止嵌套”,而是:别让阅读者层层绕路,翻好几层逻辑才找到核心意图。
我的经验是:
嵌套超过三层的时候,大概率已经需要重构了。
2. 给复杂逻辑起名字
很多人喜欢这样写:
go
if user.Age >= 18 &&
user.Status == "active" &&
user.EmailVerified {
...
}
看似简单。
但半年后再看:
text
为什么是18?
为什么必须active?
为什么需要验证邮箱?
业务意图已经消失了。
高级工程师更喜欢这样:
go
func CanPurchase(user User) bool {
return user.Age >= 18 &&
user.Status == "active" &&
user.EmailVerified
}
调用时:
go
if CanPurchase(user) {
...
}
代码立刻变得像自然语言。在资深工程师的眼里命名绝不是表面功夫。
很多开发者会依据代码的技术属性来命名,这也是大多数人的习惯,简洁易懂:data、result、item、resp、obj、list、value 这类名称。代码能正常编译,功能也可以运行,大家便不再深究。
可随着系统不断迭代扩容,问题随之而来。命名一时爽,debug的时候就火葬场了。
资深工程师会按照业务含义命名,因为业务语义不会随代码实现的变更而失效
这样阅读成本和调试成本都会大幅降低。
很多时候:
好的函数名,本身就是最好的注释。
3. 把非法情况变为不可能
新手常见写法:
go
type User = {
id?: string;
email?: string;
role?: string;
status?: string;
};
问题来了:
所有字段都变成可选,只是因为这样 TypeScript 就不会报错了。这根本不是类型安全,这是在投降。然而用户id不存在这种情况本身就不存在。
资深工程师不只是单纯处理非法状态,而是从代码设计层面,让非法状态难以出现、无处藏身。
在动态语言中,你也可以借助数据校验、构造函数、数据模型、工厂函数或是严谨的运行时检查,践行同样的思路。
选用哪种工具并不重要,关键在于养成规范的开发习惯。
更好的方式:
go
type DraftUser = {
email: string;
role: "admin" | "member";
};
type SavedUser = {
id: string;
email: string;
role: "admin" | "member";
status: "active" | "disabled";
};
好处有三个:
- 可读性更好
- 修改方便
- 降低出错概率
这种设计哲学在Go中同样适用:不要用可选字段来回避问题,而是用类型系统来精确建模你的业务状态。
4. 让函数只做一件事
很多代码会这样:
go
func ProcessOrder(order Order) error {
validate(order)
save(order)
sendEmail(order)
updateInventory(order)
generateInvoice(order)
writeLog(order)
return nil
}
看起来很方便。
实际上违反了单一职责原则。
任何一个环节变化:
text
库存逻辑变了
邮件逻辑变了
发票逻辑变了
都要修改这个函数。
高级工程师更喜欢拆分:
go
func ProcessOrder(order Order) error {
if err := validate(order); err != nil {
return err
}
if err := saveOrder(order); err != nil {
return err
}
return completeOrder(order)
}
每个函数负责一个明确目标。
这样测试也更容易写。
5. 不要重复自己(DRY)
很多项目会出现这样的代码:
go
func GetUser(id int) {
db.Query(...)
}
func GetOrder(id int) {
db.Query(...)
}
func GetProduct(id int) {
db.Query(...)
}
逻辑几乎完全一样。
只是对象不同。
这就是重复代码。
高级工程师会抽象公共部分:
go
func QueryByID(table string, id int) {
...
}
或者:
go
type Repository struct {
db *sql.DB
}
然后统一管理。
需要注意的是:
DRY 不代表过度抽象。
有些开发者看到两段类似代码就想合并。
结果写出:
go
func HandleEverything(...)
这种巨型函数。
反而更难维护。
我的原则是:
三次重复以上再考虑抽象。
6. 错误信息要有上下文
Go 开发里最常见的问题:
go
return err
日志里看到:
text
connection failed
然后呢?
不知道。
哪个服务失败?
哪个接口失败?
哪个数据库失败?
完全不清楚。
高级工程师通常这样写:
go
if err != nil {
return fmt.Errorf(
"create user failed: %w",
err,
)
}
输出:
text
create user failed:
connect database timeout
定位问题速度直接提升。
Go 1.13 引入 %w 之后。
这种写法已经成为最佳实践。
错误处理不当,本质是开发者自负心态的体现,对于资深大佬来说,谦虚是时刻保有的心态。
我甚至认为:
好的错误信息,价值不亚于好的监控系统。
7. 代码首先是写给人看的
很多程序员喜欢炫技。
例如:
go
result := lo.Filter(
lo.Map(
users,
func(u User, _ int) User {
return transform(u)
},
),
func(u User, _ int) bool {
return valid(u)
},
)
看起来很高级。
但团队新人可能根本看不懂。
如果改成:
go
var result []User
for _, user := range users {
transformed := transform(user)
if valid(transformed) {
result = append(result, transformed)
}
}
虽然代码长一点。
但所有人都能理解。
高级工程师真正关注的是:
text
一年后
还能不能看懂
而不是:
text
今天
能不能秀技术
代码的第一读者永远是人。
资深工程师在做优化时,会兼顾代码变更的可观察性。
一项功能即便在本地或者测试环境时运行完好,合并到主干代码依旧可能存在风险:代码改动范围过大;代码差异里混杂了重构逻辑与业务行为变更;测试用例只覆盖了正常流程;配置修改未留下说明文档;回滚方案也模糊不清。
高级工程师最大的特点不是技术,而是减少惊讶
刚入行时,我总觉得高级工程师会:
- 用复杂架构
- 用高级设计模式
- 写出非常厉害的代码
后来发现恰恰相反。
真正资深的人往往更克制,更会减少惊讶。
他们会主动避免:
- 不必要的抽象
- 不必要的框架
- 不必要的设计模式
因为他们见过太多项目后期失控。
他们知道:
软件最大的成本从来不是编写,而是维护。
一个能运行三年的系统。
远比一个设计完美但没人敢改的系统更有价值。