打印
[C语言]

刚看到一片**,为什么要重写代码?和大家分享一下

[复制链接]
1544|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xlsbz|  楼主 | 2014-11-9 20:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

码农的绝大部分工作精力是在维护代码上,至少在我所工作的部门是这样的。由此观点出发,码农界形成了如下共识:

代码首先是写给人看的。

这就要求码农们在编码时,可读性/可维护性要放在重要的位置进行考量,使用简单的设计,通用的方法,统一的风格。

每个码农心目中都有一个代码的伊甸园,在那里,代码的设计良好,实现优雅,赏心悦目。代码所要表达的意思很明晰,注释恰到好处,无需猜测就能理解编写者的意图。即使有Bug出现,通过检查代码就能容易找到错误处,无需复杂的调试过程。不再惧怕需求的增加和变化,因为代码有很好的可扩展性。

但实际上,绝大部分码农维护的代码,却是两外一番景象:代码质量惨不忍睹,错误百出,码农面对蜂拥而至的Bug和新需求,加班加点,疲于奔命。不得不承认,码农是追求完美的一个群体,码农们怀着激动的心情,按捺不住重写的冲动,在码农心中,重新实现一套系统,将极大的提高代码质量,消灭Bug。需求变更时,也不再惧怕,因为轻而易举就可修改和扩展,做到了拥抱变化。码农时不时的幻想,系统如果重写过,以后的维护工作是多么的幸福和美好。实际上,每一个码农都有、或至少有过这样的冲动,我们不得不深入思考一下其原因,重写真的能带来想象中的美好结局吗?

客观原因

经过前辈开发者们前仆后继呕心沥血的堆砌,摆在我们面前的代码库,就如同瓦力在末日世界执着搭建的垃圾大厦,表面上看非常整齐,仔细看去,就是一块块垃圾拼凑而成,代码库中充斥着烂代码。

代码质量

好的代码大致相同,烂的代码各式各样。随便举一些例子:

  • 设计复杂,或者干脆没有设计,无法理解
  • 耦合严重,各个模块、功能间相互交织,无法分离
  • 代码重复,逻辑重复严重的代码,遍地Ctrl+C、Ctrl+V的代码
  • 风格杂乱,前辈码农前仆后继,都留下自己独有的代码性格和印记
  • 废弃代码,有用,或者没用,代码就在那里,只增不减
  • 注释失效,过时的注释不是好注释,误导码农的注释是流氓注释

一般认为,代码质量差,是产品Bug频发的罪魁祸首。任何代码,无论质量高低,都隐藏着Bug,质量低的代码,尤为严重。

一旦出现Bug,码农的一般反应是:这不是我写的代码,这是老代码,一直就有问题。即使Bug是自己新引入的,也可以轻而易举的找出理由:“老代码太烂了,谁改都会出错”。没错,在码农眼中,代码库中的代码是如此之烂,以至于所有的问题,都可以归罪于老代码。

敏捷传说

需求是在不断变化的,码农们为此疲于奔命。有一种传说,叫做敏捷,据说可以解决这个问题。值得一提的是,目前我司的敏捷事业取得了可喜的成果。敏捷了,就不再惧怕Bug,因为有完备的测试,把Bug消灭在萌芽状态;敏捷了,就不再惧需求的变化,因为我们拥抱变化;敏捷了,就不再惧怕开发人员的变动,因为敏捷要求每个人都是全才,要掌握;敏捷了,我们不再惧怕烂代码,因为我们掌握了重构代码的神技。

敏捷是鼓励进行代码重构,提高代码质量的。敏捷倡导,代码应该拥抱变化,为了适应新的需求和变化,应不断的重构代码。敏捷认为:好的代码质量带来好的产品质量。这就鼓励码农进行代码测试和重构,代码测试给了码农信心,重构不用再担心和犹豫。

既然提到敏捷,多说点题外话。毫无疑问,敏捷实践是软件开发的最佳实践,但是把敏捷引入到管理流程中时,一定要万分小心。敏捷不是银弹,需要认清其本质,才能利用敏捷,提高开发效率,提高产品质量。而不是为敏捷所用,反而使得团队变得“不敏捷”。

主观原因

重写代码是码农内心萌生的欲望,是码农对优美代码的追求的正面体现。重写代码可能的动机有哪些呢?

  • 代码洁癖,代码整洁很重要,但是过犹不及
  • 优雅强迫症,设计要优雅,要抽象,为了适应未来的变化,可是未来在哪里?
  • 眼高手低,认为可以轻而易举的重写代码,把既有代码替换掉
  • 先苦后甜的心里预期,认为在一番努力之后,后续的维护工作将更加轻松
  • 内心泛滥的对后代码农的责任心,希望留下优秀的代码遗产,和一段传说

每个码农都有自己的代码审美观,爱美之心,人皆有之,码农希望能写出优雅的代码,维护优雅的代码,无可厚非,而且是应当鼓励的。

重写代码的阻力

但是代码重写这件事,至少在使用时间相对长的系统中,却鲜有发生。

外部原因领导的三个终极问题

领导和码农的相同点是,都关注代码的质量,不同点是,领导关注Bug的数量和严重程度等KPI指标,码农关心代码的好坏和优雅程度。码农认为愈优雅的代码,就带来愈高质量的产品,码农每每向领导游说,既有代码如何如何烂,重写之后如何如何能提高代码、产品的质量。领导总是很淡定,然后抛出三个终极问题:

  • 会不会引入新问题?
  • 对哪些功能有影响?有多大的影响?
  • 工程上有多大的风险?

重写当然会引入新问题,当然会对现有功能有影响,影响有多大,码农深思许久,依然没有把握,只好郁郁而归。

这个原因,是绝大部分码农经常提起的,也是最为码农们愤慨的,仿佛没有了这个阻力,将是一片广阔的天空,可以尽情施展自己的才华。

玄机暗藏

那些年,前辈码农和Bug们决战光明顶,为了改好Bug,使出了浑身解数。在烂代码上改Bug,用更烂的方式去修改,是一种快速讨巧,深受领导喜爱的方式。因为,方法虽烂,但是很好的解决了当前问题。事实证明,使用烂上加烂的方式,解决了Bug,而没有引入新问题,没有影响到既有的功能,将工程的风险控制到最小,圆满的回答领导的三个终极问题。

每个改过无数Bug的码农,都素有谦卑之心,深藏功与名,不着痕迹,以至于后代码农看到一段让人惊讶无比的代码,却不知这里暗藏玄机,封印了系统的大Bug。代码也成了一个宝藏,富含前辈码农积累下来的宝贵财富,可是隐藏的太深,无数的淘金者都失败而归。这些隐藏的知识宝藏,逐渐的成为历史,慢慢的,历史成为传说,传说成为神话。

在冒冒失失乱改一通,载了跟头,被领导臭骂之后,我们这些后世码农,在审视和修改代码时,始终怀着敬畏之心。时常用身临其境的代入感,去感受前辈码农内心的纠结和矛盾,体会他们审时度势,不得不忍痛写出如此令人不解的代码时的复杂心情。于是我们处处谨慎,不敢随意改动,总是左思右想,谨防唤醒沉睡中的Bug Boss。

内部原因1984

工程风险、领导的要求,担心改出Bug,码农被重重包围,工作中每一步都慎之又慎,不敢越雷池半步。注意!老大哥一直在盯着你!

烂代码不但带来糟糕的产品质量,也带来大的代码变更成本,修改一句代码往往都意味着工程风险,领导的责骂,自身的惶恐。更严重的是,烂代码将一步步浸染开发者追求“美”的初心。为了熟悉业务,不得不顺着既有代码的思路;为了新增功能,不得不堆砌更多的烂代码;为了解决Bug,不得不浸泡在烂代码中,无法自拔。潜移默化是最厉害、最彻底的变化方式,不知不觉间,开发者找到了成本最低的工作方法:以烂代码的思考方式解决问题,堆砌更多的烂代码。

失去了“初心”的码农,一边在挣扎,一边继续沉沦,沉沦于“舒适区”。码农已经完全忘却了曾经拥有的“初心”,没有了挣扎,并在彻夜未眠终于解决一个故障后露出了欣慰的笑容。终于,码农没有了抱怨,他在享受。

代码江湖

代码就是江湖。码农是江湖中行走的剑客,剑客们心怀天下,行侠仗义、快意恩仇,梦想着有朝一日一统江湖。可是,江湖险恶,危机暗藏。初入江湖的新手剑客,学艺不精,却心比天高,不畏艰险。浪迹江湖多年的老道剑客,往往知道水深而不敢涉险,因为他们已渐渐读懂江湖。

新手剑客,让其路见不平,拔刀相助是一件很容易的事情;但是让其谦虚谨慎,静待时机却非易事。仗剑江湖比读懂江湖要来的容易,这是一个知难行易的典型例子,我们也喜欢这样的故事。码农何尝不是?新手码农路见Bug,便想祭出重写之剑,可是却不愿意去读懂既有代码。

可是,重写代码真的比读懂代码容易吗?新手剑客是否已经剑术精湛,内功深厚,认清了江湖,才能仗剑江湖。新手码农是否夯实了技能,深入理解了要解决的问题,无法驾驭既有代码,便不可能重写出理想的代码。

江湖老鸟老罗,在其Rom发布会开头的发问:“大家准备好了吗?”,我们要时常问自己:对于彻底革新整个系统或者模块,真的准备好了吗?

总结

面对阻力时,我们的注意力往往集中在外因上,码农经常抱怨的也是,如果领导同意,代码早已经重写,而不会造成现在的这样一个烂摊子。却往往忽视了自身的原因,码农往往宁愿躲在“舒适区”内哭泣,也不愿意折腾之后满足的笑。

重写代码的冲动是应当珍视的,没有推翻陈旧的勇气和行为,就没有大的进步。可是,我们是否就可以大胆的对代码进行重写呢?对系统/模块是否真正掌握了?如何获取隐藏的知识?敏捷是不是万能的良药?测试能带来多大程度的保证?

带着这些问题,我们还需要做进一步的思考。

本码农四年码历,经验尚浅,以上所述,空闲时的一点思考,不当之处,欢迎批评指正!

相关帖子

沙发
cjseng| | 2014-11-10 12:28 | 只看该作者
楼主所言极是!
看着自己以前写的代码,心中甚是惶恐、不安、内疚、羞愧,这狗屁不通的代码竟然是自己写的?恨不得立马推倒重写为快。
可是,当初写这些代码的时候,一遍遍测试,一个个排除BUG的惨痛经历虽然已经印象模糊,但是还是心有惧意的。想来,写代码的过程不会一帆风顺,重写可能也不会太顺利,甚至,以前走过的弯路,可能还要重走一遍,因为时间久远,当初的教训都忘记了。
为了赶进度,往往用一堆狗屎一样的烂代码去消除BUG,处处拦截BUG,将BUG隐藏起来,以免对项目产生影响,却无法找到BUG产生的原因,这是最令人痛苦的事。虽然,对这种做法早已深恶痛绝,但是在下一次写代码的过程中,却又身不由己,重蹈覆辙。
有时候,我想,如果给我一年的时间,我可以把这段代码写得很好,可现实是残酷的,往往只有1个月的时间甚至更短,那么,奢求代码的完美却又是不可能的事了。
幸亏,在不断写出一坨坨狗屎般的代码的过程中,已经逐渐熟悉了如何堆砌狗屎的技巧,狗屎依然是狗屎,不过,外观看起来似乎还算可以,总算表面光鲜,而且,也总能解决问题。慢慢地,也就沉浸在用狗屎解决问题的快感中了。
终于有一天,要把这表面光鲜的代码移交给新人,却又惶恐起来,担心自己高大上的形象忽然间轰然倒塌。
说完代码,还要说说画PCB,毫无悬念,看以前画的板子,也只能用惨不忍睹来形容,那是另外的一种狗屎。同样,也每每产生重画的冲动。但是,重画意味着投入时间、精力,却不见得有什么回报,只是因为,狗屎般的板子,却可以正常使用,重画之后,还要反复测试,万一哪儿改错了,嘿嘿。。。。
一个新的产品交到客户手里,在很长一段时间内,我会一直惴惴不安,不知道隐藏的BUG哪一天会爆发,因为BUG无处不在。这种情绪在我工作的最初十年中,一直笼罩在心头。
只不过,到了现在,我已如老僧入定般的淡定,没有BUG的世界是不完美的,你愿意,不愿意,BUG始终都在。



使用特权

评论回复
评论
xlsbz 2014-11-11 14:57 回复TA
好1 
板凳
airwill| | 2014-11-10 23:15 | 只看该作者
看来都是有和烂代码打过仗的经历.
也是在烂代码中思考和总结, 将代码质量一步步提升.

使用特权

评论回复
地板
xlsbz|  楼主 | 2014-11-10 23:27 | 只看该作者
airwill 发表于 2014-11-10 23:15
看来都是有和烂代码打过仗的经历.
也是在烂代码中思考和总结, 将代码质量一步步提升. ...

版主还不睡觉  双11购物?

使用特权

评论回复
5
shiop77| | 2014-11-11 14:53 | 只看该作者
不错的好**,感同身受啊

使用特权

评论回复
6
flyingleavesqi| | 2014-11-12 16:08 | 只看该作者
如果要重构代码,需要时间和安排。
系统构架,模块划分,抽象数据结构,分层,代码实现。
亲身经历,前辈代码维护2年,重构优化和测试花了2年(期间继续维护前辈代码),任然会有bug。
个人感觉,就算对前辈代码了如指掌,自己重构的时候还是会有不尽如人意的地方。
我改的这个程序构架,用了7-8年了,代码规模1W行左右,如果是10W和100W行的代码,重构花的时间就会更长。
汽车发动机控制器(ECU)的代码大约10W,用了30年,即使无数bug和补丁,但是没有人敢重构。

使用特权

评论回复
7
just_so_so| | 2014-11-12 17:59 | 只看该作者
写的非常好啊,引起了许多共鸣,共勉。

使用特权

评论回复
8
xlsbz|  楼主 | 2014-11-12 19:03 | 只看该作者
flyingleavesqi 发表于 2014-11-12 16:08
如果要重构代码,需要时间和安排。
系统构架,模块划分,抽象数据结构,分层,代码实现。
亲身经历,前辈代 ...

别人的东西最好别改。这一点很重要。
我的做法是彻底革命,推倒重来。
当然自己有把握才行。

上层支持也很重要。
否则能力再强也是百搭。

使用特权

评论回复
9
xlsbz|  楼主 | 2014-11-12 19:05 | 只看该作者
flyingleavesqi 发表于 2014-11-12 16:08
如果要重构代码,需要时间和安排。
系统构架,模块划分,抽象数据结构,分层,代码实现。
亲身经历,前辈代 ...

重自己的构。而不是别人的构。前者难度相对较小。

使用特权

评论回复
10
kakaoracle| | 2014-11-12 23:03 | 只看该作者
没有人会只写完美代码,今天的优秀都是日复一日的苦练结果

使用特权

评论回复
11
fu29159686| | 2014-11-13 13:25 | 只看该作者
没看懂

使用特权

评论回复
12
xlsbz|  楼主 | 2014-11-16 19:24 | 只看该作者
fu29159686 发表于 2014-11-13 13:25
没看懂


逻辑缜密。有条理。
写的不死板,不花哨,刚刚好

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

190

主题

1614

帖子

4

粉丝