猪小兵的故事
程序员为什么会重新发明轮子?原因很多,从狭隘的技术原因到程序员心理状态,再到软件生产系统的经济学,方方面面都会导致如此行为,这种特有的顽疾正在蔓延。
猪小兵是个刚走出大学的程序员,拿到了第一份正式工作,让我们假设他或她已经知道了代码重用的价值并且满怀青春的准备大干一把。
小兵的第一个项目是随团队编制一个大型应用。为了实例说明的方便,让我们认为那是一个帮助终端用户能够智能构造查询和浏览庞大数据库的 GUI。项目经理已经组合了他们认为适合的工具和组件集,不仅包括开发语言,也包括许多程序库。
那些程序库对于项目来说至关重要。它们包装了许多服务–下到窗口构件和网络连接,上至诸如交互帮助的整个子系统–否则需要特别大量的额外编码,会严重影响工作预算和发布时间。
小兵有些担心发布时间。他或许缺乏经验,但他知道管理上有个趋势,说得好听点,进度上比较"积极"。
一切要比他想的费时和痛苦。在程序库表面光鲜的示例程序下,正在重用的组件似乎在一些边界情况下表现得无法预料或具有破坏性—而这些边界情况在他的代码中常常遇到。小兵经常奇怪写程序库的家伙究竟是怎么想的。但他没法知道,因为组件的文档不全–那些文档是技术文员写的,他们既不是程序员,想问题的方式也不像程序员。他也不能通过阅读源码来了解程序库究竟是干什么的,因为程序库是处于专有许可证下不透明的目标码。
小兵不得不为组件问题不断的编写复杂的迂回代码,使用程序库已经到了得不偿失的地步。迂回方法使得他的代码越变越糟。他碰到了程序库的软肋,库无法简单的像其规格说明那样完成某些至关重要的任务。有时他也确信肯定有某种方法可以让这个黑盒子跑起来,但却无法断定究竟是什么方法。
小兵发现,随着在程序库上花费的精力越多,他的调试时间就越成指数级的上升。代码处于崩溃和内存泄露的痛苦之中,追下来又往往发觉祸根就是那个程序库,或者是某些他无法查看和修改的代码。小兵知道再追也许会追回自己的代码,但是没有源代码,就算想追回到自己的代码也是不可能的。
项目进度在变缓,梦想成为架构师的小兵发现,自己简直成了砖瓦匠,正在试图用堆不起的砖盖房,而且压力一大就会塌掉。而经理并不想听到新手的借口,大声的抱怨组件质量太差,那些选择组件的经理和高级人员之间肯定会找他的麻烦。而且即使能够成功说服他们,改换组件也将是一个复杂的提议。
除非小兵非常,非常幸运,他不可能在项目的有生之年修正程序库的 bug。在清醒的时候,他也意识到库里面也有许多能工作的代码,他太注意那些 bug 和疏漏了。他很愿意能够坐下来同组件的开发者好好谈谈,他们又不是白痴,从他们的代码能看出来,他们一样是程序员,也工作在一个令人受挫的系统中。但是小兵甚至不知道他们是谁—而且即使能知道,他们就职的软件商也多半不会让他们同他讨论这个问题。
绝望中,小兵开始打造自己的砖块—用较稳定的库模拟不太稳定的库,并且开始从零编写自己的实现。用来置换的代码是他自己的,思维模式他一清二楚,并且能够反复阅读,更新认识,比起被替代的不透明组件和迂回方法所混合的代码,往往工作的相对更好也更容易调试。
小兵学到一个教训:越少用别人的代码,他的代码产量越高。这个经验满足了他的自尊。像其他所有年轻的程序员一样,在思想深处都觉得自己比别人聪明。他的经历也似乎在表面上证明了这一点。所以小兵开始构建属于自己的工具包,一个自己用起来更顺手的工具包。
不幸的是,小兵此时获得的自己动手的习惯性思维,是一个短期的局部优化,会引发长期的问题。他或许可以编写更多行的代码,但是如果不能重用,这些代码产生的实际价值很可能会相当大幅度的降低。代码多并不等于代码好,至少在编写低层次代码和大量重复投入时是如此。
在换工作时,小兵至少还得准备经历一个挫折。他很可能发现带不走他的工具包。如果他带着在公司编写的代码走出公司大门,其旧雇主就有理由认为他侵犯了知识产权。如果承认重用了旧代码,新雇主如果知道了,也大有可能很不爽。
即使小兵能够偷偷摸摸的在新工作中使用原先的代码,他也会发现自己的工具包用处不大。新雇主也许使用一套不同的专有工具,语言和程序库。极有可能的是,在每个新项目中,小兵都不得不学习一个稍微新一点的技术并重新发明一套轮子。
这样,程序员重用代码便是技术问题,知识产权壁垒,行政问题以及个人自我意识的综合。成千上万的小兵们年复一年的随着年龄的增长,变得越来越愤世嫉俗,也越来越习惯那种系统。对于多数软件行业的现状,这就是巨大的时间,资本和人力资源浪费。
小兵经历反映的职业文化可以折射出大部分的情况。软件公司有种"非自己做不可"的强烈情节。他们对于代码重用是矛盾复杂的,一方面为了赶进度逼迫程序员使用功能不足但很有市场的商业组件,同时又拒绝重用程序员自己经过良好测试的代码。这些软件公司费力生产的是大量专用重复的软件,其实编制软件的程序员知道结果会是垃圾,但除了自己的代码,别的哪也动不了。
代码好不容易写出来了就决不能扔,只有不断修修补补,即使所有的人都知道扔掉重写会更好些,这个教条,就是在这种文化里形成的最接近代码重用的对等物。这种文化产生的产品,即使其中涉及的每位人员都尽最大努力最好工作,随着时间的推移,写出的程序还是会变得越来越臃肿,bug 也越来越多。