- 大话编程
- 一个故事讲完 https
- C 老头和 Java 小子的硬盘夜话
- 我是一个函数
- 操作系统是个大骗子?
- 90 后 老头儿 和 00 后 Go 小子的硬盘夜话
- 爱炫耀的数据库老头儿
- 浏览器:一个家族的奋斗
- 浏览器家族的安全反击战
- 黑客三兄弟
- 从读写分离到 CQRS,张大胖是如何解决性能问题的?
- 两个程序的爱情故事
- 两个程序的爱情故事(续)
- 烂代码传奇
- 机房夜话
- 干掉状态:从 session 到 token
- 张大胖的 docker 之路
- 从 SOA 到微服务
- XML 的传奇人生
- 从密码到 token, 一个授权的故事
- 编程世界的那把锁
- 加锁还是不加锁,这是一个问题
- 这个动物园, 两年也逛不完
- 张大胖和 CAP 定理
- 一个翻译家族的发家史
- 张大胖和单元测试
- Java 帝国
- 一个著名的日志系统是怎么设计出来的?
- Java 帝国之泛型
- Java 帝国之动态代理
- 从兄弟到父子:动态代理在民间是怎么玩的?
- Java 注解是怎么成功上位的?
- Java EE 要死掉了?
- Java 帝国之宫廷内斗
- Java 帝国之宫廷内斗(2)
- 当世界上只剩下一个 Java 程序员
- 持久化:Java 帝国反击战
- 什么是框架?
- 学习 Java 虚拟机没用? 听听当事人是怎么说的!
- 聊聊 Java 平台上的非 Java 语言
- Java 帝国之消息队列
- Java 帝国之 JMS 的诞生
- Java 帝国之单例设计模式
- 对 Java Inputstream 的一次采访
- ASM: 一个低调成功者的自述
- 序列化: 一个老家伙的咸鱼翻身
- Java IO 的自述
- JDK 先生最近有点烦
- 什么是框架(续)?
- 说 空话,做实事: 谈谈多态
- Kotlin 初体验
- 小白科普
- 小白科普:分布式和集群
- 什么是 Zookeeper?
- 小白科普:悲观锁和乐观锁
- 小白科普:LDAP 有什么用?
- 小白科普:服务那点事儿
- 小白科普:Netty 有什么用?
- 老司机经验
- 后端程序员都做些什么?
- 为什么要学习 HashMap 的底层原理?
- 小心,别被今日头条给困住了!
- 对自己狠一点,开始写作吧
- 开源代码啃不动,不如先定个小目标
- Python 这么简单还用学吗?
- 作为一个有追求的程序员,你应该掌握的七种武器
- 给设计模式说句公道话
- 时间是这么被浪费掉的
- 你真正付出了全部努力了吗?
- 写给初学者:编程的本质
- 在大学期间更应该学习什么?
- 看看 悲催 的码农得学多少东西?
- 学习编程的四兄弟
- 那些年,我后悔没做好的事情
- 我为什么对后端编程情有独钟?
- 当我们在学习编程语言时,我们在学习什么?
- 编程需要多少数学知识?
- 想成为编程高手,一定要学汇编吗?
- 你必须理解的计算机核心概念
- 你的需求是怎么描述的?
- 白话敏捷软件开发
- 人在职场
- 凡事必先骑上虎背,给性格内向的程序员聊几句
- 为什么能力优秀的人当了主管以后反而不行了呢?
- 不想做技术了,还有一条路
- 纪念我最有效率的一次加班
- 书写「简历」时,需要规避的错误。
- 上天还是入地?
- 工作 6 年,半路出家到 CTO
- 只是 Work 还不够,更重要的是 Think
- 我所尊敬的三位女程序员
- 我们向印度人学习什么?
- 你去下家面试,怎么评价你在这家公司做的工作?
烂代码传奇
现在你们管叫我烂代码, 实在是委屈我了,想当年我年轻的时候,那可真是人见人爱,花见花开,气质高贵,身段优雅,无数程序员对我着迷。 那个时候你们叫我什么来着? 好像是优雅代码、漂亮代码吧。
但是请注意,虽然被你们称为烂代码,我可是一直在生产环境上运行的代码啊,支持起成千上万的并发访问和计算,所以准确点儿说,我叫 遗留代码 。
我为什么会变成这样, 你们程序员负有不可推卸的责任,如果你看看我的版本管理历史,对,就是 2010 年以前, 还能看到年轻而漂亮的我。但也是从那个时候开始, 多变的需求、进度的压力、人员的素质、混乱的管理, 让我慢慢走向了这条不归路。
我清楚的记得那一天,一个叫小董的程序员奉命开发一个新功能, 要对我这一块代码进行改动, 当时有两个方案,一个是对我重构,继续保持优雅的身段,但是工作量比较大。
另外一个是就地修改,只需要寥寥几行代码即可,代价是需要加上我极为讨厌的类似 if(p instanceof XXX) {......}这样的代码, 在进度的压力下, 小董为了少加班, 没有顶住魔鬼的诱惑,不假思索地选择了后一种方案。
我本来想抗议一下, 但是看着他睡眼惺忪的眼睛, 想到他昨晚加班到凌晨 3 点才睡, 心就软了。
体谅一下码农,忍了吧, 不就多了一个看起来非常丑陋的 if 分支吗?
小董的代码被传到了组长那里做 Code Review, 曾经要求非常严格的组长这时候忙得四脚朝天,根本没时间细看,这段丑陋的代码作为漏网之鱼,轻松进入了版本管理系统的代码仓库。
心太软的后果很严重, 这个丑陋的 if 分支如同我漂亮面孔上的一道伤疤, 开了一个恶劣的先例,时刻在诱惑着程序员们: 大家都不用有心理负担了, 以后想怎么改就怎么改,反正已经开始腐化掉了!
三天以后, 张大胖毫不留情的在这里补了一刀,又是一个丑陋的特殊判断! 不过张大胖还算良心,写了“长达”10 个字的注释,努力地辩解代码的意图,实际上我内心非常清楚,这 10 个字完全词不达意,把人带沟里的可能是 99%。
一周以后,项目进度依然落后, 经理招了一大批新人入职, 终极“杀人王”小李出现了!
小李是个典型地使用面向对象语言写面向过程代码的年轻人, 刚进团队的时候,他还纳闷说这个项目的代码怎么和自己见到的、自己写的不一样呢? 这里的代码读起来怎么这么难理解 ?
其实他不知道,面向对象的代码由于是针对接口编程, 每当你去找接口实现的时候是比较费劲的, 比起直接的面向过程代码, 读起来是个不小的阻碍。
然后小李便发现了被改得面目全非的我, 熟悉的配方,熟悉的味道, 他欣喜若狂, 举着一把杀猪刀, 在我这里大砍大杀, 我疼得昏倒在地,在被编译器唤醒以后,看到这数不清的伤疤,我吐血三升,再次晕倒。
拖着伤痕累累的身体,我和伙伴们又进入编译器, 让它把我们编译成二进制代码,这些二进制代码长得都差不多,也无法看出曾经的丑陋伤疤, 他们乐呵呵的奔向生产系统。
编译器看到我们的疑惑,解释说: “你们这些源代码主要是给人看的,所以很在乎自己的外表, 但是二进制代码是让机器执行的,都是指令而已,根本不关心长得如何, 能执行就行。”
我心里一阵羡慕:二进制代码的生活真好,单纯而快乐。
一年以后,这个系统的源代码已经变得凌乱不堪,极难维护了。 有一回高层领导震怒了: 为什么新加一个小小的功能,你们这里都得改一个月? 客户可等不及啊, 加班!
可是加班也不行, 代码太难懂了,这简直就是一片黑暗丛林, 程序员通常是有去无回。
领导又说了,你们的瀑布开发流程有问题, 现在敏捷软件开发很有效,赶紧转型敏捷。
于是敏捷教练来了,看到我们这些烂代码,不由的露出了得意的笑容: “看看, 和我之前估计的一模一样吧,这么烂的代码你们还想迅速响应市场变化? 一定得重构啊 ”
可是没有人敢重构我们这些遗留代码,张大胖说:“不是不想重构,是不敢啊, 这代码牵一发而动全身, 万一该改错了怎么办?”
教练说: “想重构必须得有测试, 你们得先写测试用例!”
那就写吧, 在教练的指导下,开始轰轰烈烈的单元测试运动, 可是刚推进没多久就被迫停止了,因为我们这些遗留代码很难写测试, 我们经常依赖数据库,网络,文件系统的数据,按照单元测试的做法,需要把他们用 Mock 技术给模拟出来, 但是想 Mock 的话代码中也得有“接缝”才行。
(注: 接缝的概念来自于《修改代码的艺术》, 指的是是指程序中的一些特殊的点,在这些点上你无需做任何修改就可以达到改动程序行为的目的, Mock 代码通常可以在这里安插)
但是我们这些“烂代码”中哪里有“接缝”? 为了提供接缝,就必须在没有测试保护的情况下对遗留代码进行修改, 这就回到了原始的问题, 张大胖他们不敢改啊。
敏捷教练说张大胖你们得有勇气做啊,张大胖说你真是站着说话不腰疼,万一改错了你又不承担责任都是我们的锅我们必须来背你拍拍屁股就走了.....
教练无语,真的走了。 有人提议重新写, 但是也被否决, 原因是业务这么复杂,重写怎么能考虑到这么多细节, 重写出来的代码 Bug 会更多!
于是只好保持现状,三年过去了, 开发人员都换了一茬,能够透彻理解系统的人几乎没有了。
经历了这么多事,我也就破罐子破摔了,完全不再在意自己的相貌。
有些时候,程序员为了理解代码逻辑, 翻起了代码的早期版本,惊叹于当时的优雅代码,我也就有机会跟着自我陶醉一下,仅此而已了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论