看到该书的前言时,我承认被这张图惊到了
这不就是我看某十年以上老项目代码时的体验吗?到处都是Shit! Shit!
肥肥的几百行一个的乃至上千行一个的函数,功能复杂到与其他的各种东西相干涉,千奇百怪的变量名,怪异的缩写(Bcsval,Rbsrbph,都什么玩意儿),多年不敢碰的配置文件...
增加点直观印象:
SISDOUBLE fSA = 0.0f; // Sum Assured on death
SISDOUBLE fCSV = 0.0f; // Cash Surrender Value
SISDOUBLE fDisN = 0.0f; // Disclosure factor
SISDOUBLE fDisS = 0.0f; // Disclosure factor
SISDOUBLE fTC = 0.0f; // Total coupons
SISDOUBLE fAC = 0.0f; // Total accumulated coupons
SISDOUBLE fTRB = 0.0f; // Total reversionary bonus
SISDOUBLE fRB = 0.0f; // Reversionary bonus
SISDOUBLE fSB = 0.0f; // Terminal bonus on surrender
SISDOUBLE fMB = 0.0f; // Maturity bonus
SISDOUBLE fDB = 0.0f; // Terminal bonus on death
SISDOUBLE fAFacto = 0.0f; // A-factor for calculation of cash value of bonuses
SISDOUBLE fADFactor = 0.0f; // Adjustment factor calculation of cash value of bonuses
虽然有注释,但用着用着,已经不知道它是干什么的了。
而且你还千万别碰,碰了就出事。
感觉代码已经脏到了这个地步(别吐):
这些几十万行代码虽丑,但功能却强大,是一个很重要的数据引擎,至今被使用...
这些代码已经很难看了,但紧张的时间,以及“反正已经这样了,再加一些也没啥”的想法,使得开发者只是继续前任的行为,继续补丁加补丁的开发着。
而且由于破窗效应:环境中的不良现象如果被放任存在,会诱使人们仿效,甚至变本加厉。
这些程序的维护者,包括我在内,觉得反正这个项目的代码已经是这样了,增加和维护功能时,不太在意代码的整洁,随意的添加着补丁,给后人带来更多的理解困惑。
生产力的下降是必然的,象屎一样的代码,和更多象屎一样的代码...
是的。
如果放任代码,只会越来越脏。
让代码尽可能分割开,而不是堆一处,是减少WTF的基本原则。因为,如果一个文件只有一处脏代码,即使总体上有千千万万的脏代码,大脑还是可以处理得过来的。
然后,再利用黑盒原则,在输入和输出处做好足够的注释,甚至可以忽略文件内部的脏代码,继续使用,日后再重构。
进度和优化的矛盾在于,时间只有一份,用来赶进度,就没时间优化。
但是,如果不优化,赶进度的过程里将会浪费更多时间。
优化的好处,是隐形的。因为,经你优化过的,在使用的过程中,不会出现问题。不管是老板还是你自己,都不会把时间的节省归功于优化。
赶进度的弊端,是隐形的。因为,只要用户量不大,边际条件没有并触碰,脏代码就还是可以“良好运行”。
脏代码积累到一定程度,才会让人开始觉得“费劲”、“无从下手”。这个时候,想优化,因为牵一发动全身,往往又太困难。
那怎么办呢?
我觉得,只能把代码尽量分割,让以后的重构更容易一些。
哈哈, 插图很生动形象
昨天晚上看了序和前言, 被一个词打动了----"代码感", 这不就是每个程序员应该追求的东西吗. 一种可以和艺术感相提并论的
感觉, 而她专属于程序员. 作为一个程序员, 你要是缺失了这种感觉, 那得多亏啊!
想想你每次写完一块功能的代码, 回过头来看这些代码, 你竟然被她美到cry...这是种什么样的体验, 肯定很爽!
Good or Bad?
肯定不是一下子就知道的. 都是基于之前的积累得出的结论. 又如同吃烧饼一样, 吃到第9个才会吃饱, 那么前面的8个烧饼都一无是处吗? 所以我一直不赞同 那些一味的批评前辈的代码的人. 如果换成你自己,也未见得能写出更好的. 毕竟每个人做出选择都是有理由的, 能写程序的不会笨到哪去. 在某个特定的场合,就写出那种代码,很丑但是很温柔。
因为不管是什么问题, 最后出问题都会指望着程序来解决. 数据错了. 流程不合理. 等等. 高压之下:肯定有 hack code. 就是诸位看到的脏代码了. Hold住就还好. Hold 不住还会躺着中枪.
但没有银弹,只是会有一些大的策略和原则. 如何理论化是困难的. 实践起来更是如此。
防御型编程的思路: 就是会花一些额外时间来写与功能无关的代码, 但可以方便追查问题. 还可以主动写测试用例来跑自己怀疑的逻辑部分. 而一旦有一个队友是只关心自己的小模块,粗暴的修改, 必然会导致连锁反应, 看起来是修bug. 其实是让局面更加混乱. 没有code review会很可怕. 千万不能指着测试部门. 一旦上线了, 出bug时还是得落到程序头上来解决问题. 我们不是来扯皮的,对吧。
没有银弹,重构不是万能的,也许只是又开始新一轮的代码制造,然后老版本废弃, 新bug产生. 升级大法好. 老bug一下子就没了.
出来混的,早晚要还的.
代码写多了,不好好维护,不想办法好好维护, 总有一天会出大问题. 我信了.