如何编写不可维护的代码
【翻译:How To Write Unmaintainable Code】
让他通过卫生纸筒子去看你的代码,让他一次只能看小小的一部分,你必须保证他在做这种工作时,永远不能得到一张全景图。你要千方百计地让他难以找到他在查找的东西。最最重要的是,你要千方百计地让他认识到,忽略(ignore)任何东西都是不安全的。
程序员们常常被哄骗着安心于规范。你要在每时每刻通过巧妙的违反规范,迫使他用放大镜去读你的每一行代码。
你可以从语言的每一个特性(feature)上获得灵感,产生不可维护的代码,当然只是恰当的滥用。
我会介绍一些技巧,告诉你如何编程。让你的后继者赞叹这些代码怎么这么难以维护,以至于花几年的时间都不能做最简单的修改。更进一步,如果你虔敬地遵循这些规则,你会确保你的饭碗,因为没有除你之外的任何一个人能够承受维护你的代码的炼狱。嗯,再说了,如果你虔敬地遵循这些规则,可能你自己也不能维护这些代码。
你不想做得过火了,你的代码不应该看上去毫无维护的希望,否则它们就可能陷入重写或者重构( refactoring )的危险之中。命名术
在你编写不可维护代码时,大量的技巧在于变量和方法命名的艺术中。编译器完全不理会这种事情,这就给了你一个巨大的自由创作空间,去迷惑维护程序员。
买一本婴儿取名的书,你就永远不愁找不到变量名了。Fred就是一个好名字,又容易输入。如果你喜欢容易输入的变量名,试一试adsf或aoeu。
如果你把变量取名为a,b,c,则不可能用简单的文本编辑器搜索它们。而且,没有人能够猜出它们代表什么。如果有人想打破从FØRTRAN语言以来,我们捍卫的使用i、j和k作为变量的传统习惯,即用ii,jj和kk取代它们,则告诉他们西班牙宗教裁判所是如何对付异教徒的。
如果你不得不使用描述性的变量和方法名,misspell它们。通过误拼一些变量和方法名,而在其他地方有正确的拼写(例如SetPintleOpening,SetPintalClosing),我们有效的阻击了使用grep(regex工具)或 IDE 搜索技术的企图。它有令人惊讶的功效。同时,我们还可以增加一些国际化的风格,比如在不同的场合(theatres/theaters)使用tory or tori的拼写方式。
在变量和方法名中,大量的使用抽象词汇,如it, everything, data, handle, stuff, do, routine, perform和数字,比如routineX48, PerformDataFunction, DoIt, HandleStuff,还有do_args_method。
6. 同义辞典大法
为了丰富多彩避免单调,请使用辞典,就相同的行为(action)找出尽可能多的可替代的词汇, 如: display, show, present等等。这里模模糊糊地暗示了它们有微妙的差别,而事实上却不存在这种差别。但是,如果有两个相似的函数真正有重要的不同, 你就应该总是采用同一个词来描述这两个函数 (例如 print用于表明“写入文件”, “把墨水涂在纸上”以及“打印到屏幕”)。无论什么情况下,有人要求你把这个特殊项目的词汇用明白无误的定义写成一个词汇表时,千万要挺注,别趴下,因为那样的做法,违反了结构化设计的重要原则——信息隐藏,会显得不够专业。
7. 采用非英语的复数形式
有一种VMS脚本【OpenVMS,是一种操作系统】能从各种Vaxen中返回statii。【不懂什么意思】。具有这种资格的语言还有Esperanto(世界语),Klingon and Hobbitese【自己去了解这些可爱的语言吧】。对于Plural,可以加-oj来借鉴世界语的复数形式,pluraloj。你这样做,也是在为世界和平贡献自己的微薄之力。
8. CapiTaliSaTion(大写)
一个单词中的某音节的第一个字母,采用随机的大写方式。【capitalization 写出CapiTaliSaTion就是好例子】,例如:ComputeRasterHistoGram()。
【computeRasterHistogram计算光栅直方图】
9. 名字的复用
只要该语言的用法允许,给类、构造器、方法、成员变量、参数、局部变量取相同的名字。【我特别奉献一个可编译的程序作为例子:
class YQJ {
YQJ YQJ(YQJ YQJ){
YQJ:
for(; ;){
if(YQJ.YQJ(YQJ)==YQJ)
break YQJ;
}
return YQJ;
}
}
】
特别提示,在{}块中我们能复用局部变量名【Java的局部变量不允许隐藏,但是在不同的{}块特别是初始化块中使用复用技术,是合理而且聪明的——yqj2065特别推荐】,目标是迫使维护程序员仔仔细细地检查每个变量的作用域(scope)。特别指出,在Java中要把普通的方法化妆成构造方法。
10. 带声调的字母
采用带声调的字母作为变量名。例如:……【我特别奉献一个可运行的程序为例子:
public class Test{
public static void main(String args[]) {
int Ε=5;
int E=5;
System.out.println(Ε+ E);
}
}
原文中的方法很有些过时了,我们要充分利用Unicode给我们带来的机遇和挑战。一定要让他去买一个放大镜。】
……