我最近的作为一个Rails程序员的经历可能并不常见。
我经常被叫去维护一些已经做好的Ruby/Rails项目,在力所能及的地方进行改进和完善。这样,绝大部分我需要接手的项目在我出现前都已经开发完成了。事实上,在我的记忆里,我只参与了一个商业性质的格林菲尔德Ruby项目的开发。其它的,在我看来,都是“历史遗物“,相当多的程序代码在我之前都已经出品了。(不包括个人和内部项目)。
我知道,我的这种经历在Ruby和Rails程序员中并不常见。由于Ruby/Rails的高产和创业公司为主的用户环境,大多数Ruby爱好者都是在这样刚成立的公司里开发全新的项目。而我的工作更多的是基于最初的开发人员走后留下来的代码。
Rails的让人不堪的小秘密
在受雇写Ruby程序之前,我也接手过一些历史程序,它们有的历史达数十年之久,代码量数十万行之多。你很容易在这么多代码里找出写的很烂的东西;有时候,这种烂代码的数量多的让人惊讶。
但是,在Rails开发中,你会发现一个让人不堪忍受的小秘密;在我的职业生涯中,我见过的最乱的、最棘手的、最臭的代码,都是在Ruby on Rails项目里找到的。我所见过的那些Rails项目,它们两年下来积累的技术债务和废弃物,跟一个10年之久的C/C++程序相比,会让你觉得后者更干净和优雅。我说的并不是某个项目。我看到这种情况到处都是。
有时候我会想,这也显示了这种语言的强大之处。如果在一个Rails应用里有500个错误,你可以不停的往里面添加代码、再添加代码、点击“reload“,一直到它好用为止。从来都不需要写测试或重构代码。在很多语言和框架里,这种”补到它不漏为止“的开发方式显而易见是行不通的。但Ruby on Rails却提供了让你这样做的平台。
不幸的是,作为它的直接后果,众多我要处理的项目都可以被看作是一种应急产品。从某种角度来看,这种图省事的做法的后果还是由开发团队来承担,你这样做一天把它解决了,可引出的相关问题和不可预料的副作用,你花2周都解决不掉。
题外话:经常的,最初的开发人员会在完成开发后转移到新的项目上。同时会有新员工接手这些代码。管理部门会抱怨,为什么这新接手的团队修改问题时没有老团队迅速呢?而新团队遇到的问题是,在他们能给这些遗留的代码上添加新功能前,他们需要让这些代码具有更高的测试覆盖率,有可能还需要把它们分离成更小的模块;在商业层面,一个永久不变的声音是:测试和重构就是拖延工期。看来这原创团队都是比较明智的。
好了,牢骚发完了。
Rails的情况更为特殊!
Rails程序员有时候会显得很傲慢和固执。我不清楚这个判断的可信度;我并没有看到太多的人是这样,但也许我跟这个社区太接近了,也许我本身也是傲慢和固执的。
而我发现的却是一种“Rails例外主义“。还记得第一次互联网繁荣的时期吗,当时有几个经济学家跳出来说”不会的,这次不同,互联网改变了游戏规则,市场会一直走高、走高“,本质上我感觉很相似,有些人相信,Ruby on Rails开发是某种不同的东西,不需要跟其它类型的软件项目一样。
这有一些例子,让你明白我究竟在说什么:
“设计模式是Java上的东西。Ruby里只管写你的代码就是了。“
“Ruby里抛出的警告都是无聊的,禁止掉就行了。“
“的确没有单元测试,而且对象隔离做起来了很难,没有人这样做。“
“到处打补丁对于其它语言来说是不赞成的,但Ruby没问题。目前还没有出现问题。”
“像Demeter 定律这样的东西在Ruby里并不是这么重要。“
“把方法分成私有和公有,这是变态控制,Ruby里不需要这样做“
“Java代码里才会有代码异味(code smell)。“
“只有在大项目里才会有这样的问题“(暗示这个项目永远不会变大)
我还看到了很多项目和子系统例外主义者:“我知道一个类不应该搞的太大,但是对这个类是有意义的,它是为了把所有的东西放到一个地方“。
欢迎来到小人国
事实上,Ruby on Rails项目确实有一点很例外:都是小项目。上周在James Gray在Lone Star Ruby Conf大会上有个极好主题,他提到的“巨型“项目有4万多行代码。这让我微微一笑,因为我被雇来做的头两个项目分别有5万行和7万行。这看起来不少,但根据行业标准,它们很小。
造成这种现象的原因有不少。Ruby是一种比Java更富有表达性的语言,所以,从某种程度上说,Rails项目,在相同的情况下,总是比那些更讲究的语言显得更小。
而且,Rails程序员很喜欢接受把系统分割成很多很小的、相互联系的小应用。但是经验告诉我们,这种策略是有问题的。
不,我想这导致Rails应用体格较小的最大的原因是,显而易见的:这个框架还很年轻。这个领域里有大量不成熟的产品。一个Rails应用如果有3年的历史,那就可以算是古老了。
我可以很有信心的说,这种情况不会一直持续下去。我们会看到越来越大的程序项目。我不需要鼓起勇气就可以做下面的预言:很多项目将于遭遇想Lisp,Smalltalk,C++,Java等语言曾经遭遇过的相同的架构瓶颈。
你并不特殊
《programming literature from the 80s》这个作品读起来非常的有趣。动态,面向对象的系统引导了从“小规模“到”中等规模“的过度。听起来耳熟,是吧?
每一次的革命都会坚称这次是与众不同的,不会造成上次革命后出现的政党纷争和官僚腐败。起初你很容易被这些宣传感染。每个人都很兴奋,热情的去帮助;这时出现的问题还比较小;然而这只是市场的大机器还没有注意到这场运动。
事实上,你要解决的问题也许并不是你想像的那样例外。你思想里的这种拜占庭模式只是远古时代那些使用跟Ruby类似语言的人留下来的遗产。