分享一下我对好代码的理解
“什么是好代码?”——这个问题听起来很基础,但说实话,工作这么多年,真正静下心来认真梳理过的人恐怕不多。从初入职场时只管完成任务就行的“黑盒认知”,到后来开始纠结代码的可维护性、性能表现,再到今天能用稳定、体验、效率、成本这几个维度来衡量——每一位开发者的成长历程,几乎都是一部对“好代码”认知的迭代史。
这篇文章,就聊聊这个绕不开的话题。

前言
很高兴有机会把这些年对好代码的思考做个系统整理。下面会从个人经历出发,结合一些业内共识与评审标准,聊聊好代码到底长什么样。也希望这些内容能给你带来一些启发,或者至少——产生一点共鸣。
什么是好代码?
回忆入职阶段
认知黑盒:完成任务就算好代码
刚入职的时候,面对新的工作环境、协作关系和系统结构,周围的一切基本就是个“黑盒”。你不知道系统之间怎么交互,协议怎么建立的,有哪些特殊场景。所以只能在局部小心翼翼地添加代码,生怕出事。
回头想想,那时候最关心的无非是几个问题:
- 代码该写在哪里?——理想是理解链路,现实是问师兄
- 代码应该怎么写?——理想是理解上下文,现实是拷贝周围
- 代码不要出错?——理想是做好边界判断,现实是review被提示
- 代码可以回滚?——理想是做好开关,现实是过于自信
结果就是进入一个循环:开关怎么弄?重复1、2、3。
那时候理解的“好代码”,标准朴素得很:能支持需求,别出bug。
了解增多:开始思考什么是好代码
随着开发多了、了解多了,情况开始反转——不知道的变成少数,知道的变成多数。这时候能思考的内容就多了:
- 这次支持了需求,但下次改起来更困难了,这样的代码算好代码吗?
- 业务功能没出错,但埋下了性能隐患,这样的代码能算好代码吗?
从单纯完成任务,到开始思考“怎么更好完成任务”;从只顾短期设计,到考虑长期感受;从单一指标,到综合多维因素——好代码的答案,显然没那么简单了。
评价代码的一些维度
判断一段代码是好是坏,确实挺难的——因素太多,每个人的看法也不一样。那怎么评价呢?
有个标准,可能是抽象到极致了:
Martin(Bob大叔)在《代码整洁之道》里说过,当你的代码在做Code Review时,审查者要是愤怒地吼道:“What the fuck, is this shit?”——那说明你写的是Bad Code。如果审查者只是漫不经心吐出几个“What the fuck?”,那说明你写的是Good Code。
虽然抽象,但我们可以从可观察的载体来看。代码被观察的几个场景:
- 上线运行时——代码被「运行」,产生系统指标,也影响用户体验。比如耗时长了,可能没有跨单元调用;错误码直接是“System Error”,用户一头雾水。
- 遇到问题时——代码被「排查」,感受排查的难易程度。比如关键日志找不到,找到了又发现代码分块做得不好,大把的if-else。
- 遇到类似需求时——代码被「复用」,直接影响复用成本。责任不单一、抽象粒度不够,就容易老代码大改,增加风险和变更压力。
代码评审标准介绍
上面说的是个人角度的观察,但评价还需要共识。就像一道菜,你说不咸,大家都说咸,那整体上还是偏咸的。个人的判断难免主观,大家的共识才更客观。
这里分享一下部门“金码奖”的评审规则,看看共识怎么落地:
| 角度 | 解释 | 关键点举例 |
|---|---|---|
| 稳定 40分 |
代码在运行过程中具备高可用性和容错能力,保障业务连续性。 | 错误处理&边界保障:覆盖空值、越界、非法输入;异常处理完备。监控日志完备:完善日志记录和系统监控。冗余设计&版本控制:备用路径、版本回滚。 |
| 体验 30分 |
代码实现能否提升用户满意度,包括功能易用性、性能表现、交互流畅性等。 | 性能优化适配:懒加载、数据压缩、缓存设计。用户友好反馈:操作更人性化,错误提示更易懂。 |
| 效率 20分 |
代码能否高效支持业务迭代和运行——包含开发效率、运行效率、运维效率。 | 避免重复逻辑,选择最优算法;代码结构合理,支持自动化;设计灵活,支持扩展。 |
| 成本 10分 |
在资源、运维、人力成本等维度上的降低或优化。 | 避免冗余查询、减少无用计算;完善文档和知识管理;通过自动化降低测试成本。 |
评选标准最终回到业务价值——体现在稳定、体验、效率、成本四个维度。
如何写好代码
全局理解“好代码”
“神之一手”是《棋魂》里的说法,指棋手在关键时刻以超乎常理的技艺走出扭转全局的一步。对代码来说,好代码也应当在更大的范围来看——确保每一步在大局中的“精确性”,不草率落子,也不过早设计,让大家感觉“恰到好处”。
理解代码,得站在更高的层次:
- 设计模式:关注类之间的关系,如何协作完成信息传递与计算。
- 应用内架构:关注应用内的结构,体现在模块间的设计上。
- 应用间模式:关注应用间协作,功能划分与流程协作。
- 业务架构:关注系统间协作,将商业活动分解到不同系统中。
关于具体怎么养成标准,可以参考《我心中的好代码》中的对照:
| 范围 | 关注点 | 实践参考举例 |
|---|---|---|
| 点 | 变量、方法、类 | 阿里巴巴Ja va开发手册 |
| 线 | 方法、类之间关系及数据结构 | 设计模式教程 |
| 面 | 服务/应用(模块间耦合) | 应用架构分离业务与技术细节 |
| 体 | 从业务中抽象本质模型 | 领域建模 |
“坏味道”优化
前面都在聊好代码,其实反过来,避免“坏代码”,也就把代码往好的方向推了。下面几个典型的“坏味道”,可以一起体会下。
影响可读性
案例1:L的大小写。使用长整型常量时,L必须大写。小写l容易跟数字1混淆。
反例:long value = 1l; 正例:long value = 1L;
案例2:魔法值。写代码时觉得明确,调试时就不那么明确了。
反例:for (int i = 0; i < 100; i++) { ... }
正例:private static final int MAX_COUNT = 100;
性能
案例:频繁调用Collection.contains方法请用Set。List的contains是O(n),HashSet是O(1)。
反例:list.contains(i); 正例:set.contains(i);
原理Bug
案例:禁止使用BigDecimal(double)构造方法,存在精度损失风险。
反例:new BigDecimal(0.1D); 正例:BigDecimal.valueOf(0.1D);
交易链路中的设计原则和模式
学好设计原则和模式,如果能跟实际工作结合,吸收会快很多。
开闭原则
责任链模式
写好代码是一门艺术
代码怎么写,取决于很多因素——目标是什么,愿意承担什么成本。就像神经网络,最终输出的是多种变量和权重综合作用的结果,需要不断地取舍。
层次是否过多
计算机科学里有一个说法:所有问题都可以通过增加一个间接层来解决。好的分层,让大家遵循统一的分解过程,在结构上也更清晰。
但“成也萧何,败也萧何”。交易链路上,层次过多是最痛苦的问题之一——系统应用、服务入口、流程服务、活动节点、领域服务……十来个层次的透传,光打包一个上下文就得干一天起步。层次多到一定程度,理解的负担就越来越重了。
易理解性的挑战
代码的易理解性是最朴素的要求,但做到却很有挑战。
先看轻量脚本框架。好处是配置化生成脚本,减少打包部署的烦恼。坏处是,关键逻辑被嵌入框架,额外的学习成本上来了,业务开发解读不了,还得找框架维护的人答疑。
个人观察是:在层次较多的系统里,谨慎增加额外层次;引入框架前,先判断它的可维护性;多考虑长期的维护效率,而不是某一次的发布方便。
再看非功能性需求的影响。一段代码可能因为性能、可用性等要求,层层包裹,真正的业务逻辑反而被埋没了。
好的代码应该隔离关注点,把真正的业务逻辑展现出来;性能、可用性等实现,应该作为切面或策略独立出来;代码在边界场景上的正确性与可读性,才是进阶的关键。
小结
好代码的标准,是个动态演进的答案。每个开发者的工作经历,本质上就是在不停调整各个因素的权重——最终给出属于自己的判断。
这些判断通过团队的碰撞,慢慢形成共识。符合团队共识规则,是一个比较基础的答案。更好的代码出现、改变组织效率、带来业务创新,则取决于每个人的成长和时代的机遇。
说到底,你所在的位置,定义了你会写出怎样的好代码。