如何开发无法维护的软件
我靠解决技术债务养家糊口。在我的工作中我看到许多难以维护的代码,并且一次又一次地看到很多相同的原本可以避免的问题。
我专长于调试,修复,维护和扩展旧的软件系统。我的典型的客户拥有一个尚可运行的网站或内部应用,但是开发者已经不知所踪。业务需求已经改变了但是软件没有跟上。抑或我的客户有了些“快要完成”的东西但是由于预算和日程安排的关系失去了开发者。通常那包括一系列尚未完成的功能和bug。
我的客户通常被别的开发者告知需要丢弃所有的东西从头来过。大多数程序员不喜欢维护代码,尤其是维护别人的代码。当程序员写代码的时候他们总是在可维护性上问错误的问题——关于这个话题详见Matt DuVall的文章: The myth of maintainability
我在这里为你的开发项目提供了一些建议以使我有活可以干。
不要用版本控制
我总是能惊奇地发现在过去几年写的大项目不使用版本控制。如果你不使用版本控制,下一任开发者就要找出哪些文件是现有系统的一部分以及哪些仅仅是备份。他没有任何提交信息和改动日志来知悉代码的历史。我在我的文章Introduction to Abject-Oriented Programming中讲述了如何不使用版本控制。
自定义你的开发环境——越多越好
不要让下一任开发者可以轻松地上手。要求特定的开发语言版本和工具,并且确保他们和操作系统自带的版本有冲突。疯狂自定义你的Eclipse或VisualStudio或vim,然后写一些只能在那个配置下运行的宏和脚本。不要创建一个磁盘映像或者脚本来重现你的开发环境,并且不要写任何文档——那给了太多提示。
创建一个详细的构建和展开环境
把一个网站投入到正式服务器应该以下面的形式进行:
svn up git pull hg pull
程序员可以讨论代码是否简洁和优雅,然后他们转过身去建立最为详尽和复杂的展开系统。这是他们悄悄干的,不经过产品经理和客户的审查,也无法被理解的行为之一,所以它会轻易地失控。当你用不同的脚本语言把八个工具连接起来时,记得留下文档。
不要建立测试/登录平台
改变一个产品系统让人激动。不用麻烦去搭建测试或登录平台了。取而代之的,用秘密的登录方法或者用些后门URL来测试新特性。把测试数据和真实数据混合在你的数据库里。因为你没有使用版本控制,保存几份原先版本的拷贝以防万一。不要在代码里加入登录。不要在测试中关闭邮件发送,信用卡验证,等等。
将所有的东西从头写过
千万别用一个像Django, Rails, 或者CakePHP那样大家都能理解的框架。你可以写一个更好的引擎,ORM,排序或者哈希算法。当我看到一些例如“比原有字典更快的方法”或者“改变了PHP的库函数因为参数顺序烂透了”的注释时,我就要重置我的大脑。
为特殊的库和资源加上从属关系
尽可能多的加入第三方代码。连接你需要连接的库。我见过用了大量的外接库只为调用某个方法的代码。改变第三方库的源代码这样它们就无法自动更新,但是千万不要用版本控制。这样我就能发现不同的地方从而还原出原来的版本。
但是千万不要保护这些关系或者为此写文档
我接到最多的紧急电话和更新出错有关。一个看上去无害的wordpress升级,Linux更新包,或者新的jQuery版本会造成一系列实效。不要把你的代码放到特殊的或者不用的第三方库版本下检测。甚至不要加上注释。
用不同的编程语言并且紧跟潮流
每一天HackerNews和Reddit上涌现出新的酷的语言。在你的客户的东西上试试它们。任何合格的程序员可以在瞬间学会一种新语言,所以你的代码的继任者对其毫不了解也不是你的错。语言的边界,不兼容的API和数据格式,不同的服务器配置都是有趣的挑战并且值得在StackOverFlow上贴出来。我真的见过有人把Ruby嵌入PHP网站因为所有人都知道PHP很烂而Ruby更好。半吊子的caching, 流产的Rails和Node.js项目,特别是那些NoSQL方案都是我的好生意。
编程建议在哪里?
你的代码是否完美地面向对象,光鲜亮丽都无关紧要——程序员在面对旧的系统时总是一团浆糊。我擅长用diff,grep和Ctag, 追踪代码,重构和调试。我会搞清楚所有的东西。最美丽,优雅的代码如果缺少了版本控制,加上太多从属关系和自定义,并且没有测试系统的话仍然是很难维护的。这就像在一群强迫性囤积症患者中找到一间干净整洁的屋子。
如何开发无法维护的软件,首发于 博客 - 伯乐在线。