1. 这标题是个陷阱——屎山代码背后的真实警示
先讲个我自己的经历。有一次接手一个老项目,打开核心服务文件,密密麻麻两千多行,变量名从 a、b、data 到 handler、manager、utils 什么都有。我一边皱眉一边翻,在心里骂了十几次“这是哪个天才写的”,直到某天同事提醒我用 git blame 查一下,结果那几段最恶心的代码底下,赫然挂着的提交作者是我自己,时间是两年前。那一刻我沉默了,也突然就理解了“屎山代码”这四个字为什么能在技术圈引起这么大的共鸣——因为它太真实了,真实到每个人多多少少都亲手堆过几层。
屎山代码,圈内更正式的说法叫“大泥球”(Big Ball of Mud),1999年就有人专门写了文章讨论这种没有清晰结构、靠无数补丁和临时修改维持运转的系统。它从来不是一天建成的,而是无数个“先这样吧,后面再改”“这个需求明天就上线,先硬写出来”堆积起来的。但你可能也注意到了,今年“屎山代码”这个词突然又火了起来,甚至有人开始用自嘲的口吻说自己是“屎山工程师”。当自嘲变成一种集体文化时,说明大家是真的被搞痛了。
这篇文章的标题用了反话正说,说“写出屎山代码的12个技巧”,实际上是把日常代码评审、项目维护里最常见的反面操作集中起来示众。每一个技巧背后,都对应一个真实存在的坏习惯。我强烈建议你不要只看热闹,而是拿这些反面教材当镜子,照一照自己的代码。新手可以拿它建立代码品味的边界;被老项目折磨过的维护者能从中看到熟悉的痛;带团队的负责人甚至可以直接把清单变成评审红线。下面这12条,我先按“代码本身的毒化”和“工程协作的腐化”分成两批来讲,你会发现它们各自的杀伤路径很不一样。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 前六招:在代码里埋下“可读性”地雷
先看代码本身层面的六个问题。这六招的共同点在于,它们都发生在“写代码的那一瞬间”,瞄准的是未来所有要读这份代码的人。代码写出来是给机器执行的,这一点没错,但它首先是给人读的。人读不懂的代码,机器也没法长期安全地运行。前面这六招,招招都针对“可读性”下手。
2.1 技巧一:给变量起名,以别人看不懂为荣
怎么写?变量名只用 a、b、c、data、info、tmp、res、flag,需要区分多个数据时就在后面加数字,list1、list2、list3。更有甚者中英文混写,拼音和英文单词交替出现,比如 getMaxHeigh、copyDanHao、totalJine,缩写更是完全看心情。
为什么这是颗雷?因为命名是代码的第一层文档。读代码的时候,每遇到一个无意义的名字,就必须回溯到它的赋值处,搞清楚数据从哪来、往哪去。读这种代码像做侦探,每次都要在脑子里面建一张“解码表”。我印象最深的一次维护经历,是看到一个变量叫 xx,上下文完全看不出来它是什么,最后追踪了十多分钟才发现它存的是“订单流水号”。那一刻我差点把键盘捏碎,因为如果它直接叫 orderSerialNo,十秒钟就能读懂。
正确做法其实一点都不复杂:变量名要表达业务语义,布尔值用 is、has、can 开头,方法名用动词开头,类名用名词,功能是什么就写什么。把 int a = 3; 改成 int timeoutSeconds = 3;,阅读速度提升是立竿见影的。别担心名字长,长名字的代价远小于猜名字的代价。
2.2 技巧二:一个函数塞满整个业务流程
这是“万能函数”流派。一个方法几百行甚至上千行,循环、判断、数据库操作、日志、埋点、缓存刷新全塞在同一坨里,局部变量到处都是,业务规则和流程控制混在一起。你问它负责什么?它负责“一切”。类也一样,一个 Service 类上万行,打开文件光是滚动条就拖半天。
这种写法的致命之处在于心智负担。函数越长,局部变量越多,状态分支的组合就越复杂,人脑根本无法同时记住所有分支。改一个边界条件,必须把整个函数通读一遍才能确认有没有影响到别的地方。最现实的结果是:作者本人两周后再看,也要从头开始“考古”。
正确姿势是让函数短小并且单一职责。一个函数只做一件事,把每一步业务动作抽成命名清晰的私有方法,主流程只保留一串调用序列。看主函数就像看目录,想看细节再跳进去。这里我给你一个直觉上的对比:
python复制# 反面:一个函数解决所有问题
def process_order(order_id):
order = db.query("select * from orders where id=...")
if order["status"] == 1:
...
if order["amount"] > 100:
...
inventory = db.query("select ...")
# 继续往下写两百行
