Sun 的编码惯例:编码惯例,
毕竟,
Sun 也是这么做的。幸运的是,当你违反的时候,
编译器并不会透漏出去。目标就是想一些只在大小写上不一样的名字。如果你被迫使用大写惯例,
你仍然可以在任何选择不明确的时候捣乱。例如,
同时使用
inputFilename 和
inputfileName。发明你自己的异常复杂的命名规范,然后指责其他人不遵循它。
小写的 l 看起来非常象数字 1
: 使用小写 l 表示 long 常量。例如,10l 看起来更象写错的 101,而不是 10L。
摒弃任何可以明确区别以下字母的字体:
uvw wW gq9 2z 5s il17|!j oO08 `'" ;: ,。 m nn rn {[()]}。要有创造性。
把全局名字作为私有名字重新使用
: 在模块 A 中定义一个全局数组,并且在模块 B 的头文件中定义一个具有相同名字的私有数组。
这样看起来你在模块 B 中使用的是全局的数组,而实际上不是。在注释中不要提到这种重复。
循环再用
: 通过以矛盾的方法循环重用变量名来尽可能地混淆作用范围。例如,假设有全局变量 A 和 B,
以及函数 foo 和 bar。如果你知道 A 经常传递给 foo,而 B 经常传递给 bar,那么保证你把 foo
定义成 foo(B),bar 定义成 bar(A),这样在函数中 A 经常是 B 的引用,反过来也一样。
有了更多的函数和全局变量,你就能创建了非常混乱的一个网络,充满了相同名字的相关但又矛盾的用法。
再循环使用变量
: 在任何作用范围允许的规则下,重用已有但无关的变量。类似的,把同一个临时变量用于两个不相关的地方(减少栈空间)。
一种更恶毒的变体,就是搞乱你的变量,比如,在一个非常长的方法开头给一个变量赋值,在中间再赋值一次,
巧妙地改变变量的意思,例如,把从 0 开始的下标改为从 1 开始。一定不要对这个改变给出解释。
Cd wrttn wtht vwls s mch trsr
: 在变量或者方法名中使用缩写时,为了不至于厌烦可以使用同一个单词的几个变体。
甚至不时地写出普通写法。这就有效地打击了那些懒惰的程序员,他们只使用文本搜索就想看懂你程序的一部分。
把变化拼写看作是一种乐趣,例如,把国际拼法 colour 和美国拼写 color,
以及 网络用语 kulerz 混合起来。
如果你把它们完全拼出来,那么每个名字只有一种可能的拼法,对于维护者来说太容易记住了。
因为一个词的缩写可以有很多种,所以,使用缩写,就有好几个不同的变量用于同一个显而易见的目的。
额外的好处就是,维护者甚至可能没有注意到它们是不同的变量。
误导的名字
: 保证一个方法比它的名字所表明的事要多做或者少做一些。一个简单的例子,
一个叫做 isValid(x) 的方法有其他的副作用,把 x 转化为二进制并存入数据库。
m_
: 来自 C++ 世界的一个命名惯例是在类成员之前加 "m_"。这本来是用来把它们和方法区分开的,
只要你忘了方法的开头字母也是 "m"。
o_apple obj_apple
: 在每个类实例前面用 "o" 或 "obj" 作为前缀,表明你正在考虑一个庞大的多态结构。
匈牙利命名法
: 匈牙利命名法是代码混淆技术中的核武器,一定要用它; 由于被这个命名法所污染的代码量,
没有其他方法能比精心设计的匈牙利命名法攻击更快地杀死一个维护工程师。
下面的一些技巧能帮助你破坏匈牙利命名法原来的意图:
-
坚持使用在 C++ 或其他语言中代表常数的 "c",能直接增强变量的常数性。
-
找出并使用特定的匈牙利命名法,其意思在另外一种语言中与当前语言不同。例如,
在编写 C++ 代码时,对每一种控件都坚持使用 PowerBuilder 中的 "l_" 和 "a_"
{local 和 argument} 作用范围前缀,并始终使用带有匈牙利命名法的 VB 式风格。
假装不知道在那些明显可见的 MFC 代码中,控件并没有使用匈牙利命名法的事实。
-
经常违背匈牙利命名法的一个原则: 让最常用的变量携带最少的额外信息。
通过以上提出的技巧,并坚持在每个类前加上自定义的前缀,就可以达到这个目的。
绝不要让人提醒你没有前缀就表示它是一个类。这个方法的重要性也不能太过夸张:
如果你不能遵循原则,源代码可能会充斥了许多短小的变量名,从而就有一个较高的元音/辅音比。
在最坏的情况下,可能导致混淆策略的失败,并在代码中自然地再现了英语记法!
-
绝对要破坏匈牙利式的一个概念: 函数参数和其他常见符号必须用一个有意义的名字,
而匈牙利记法前缀本身就是极好的临时变量名。
-
坚持在你的匈牙利前缀前加上完全无用的信息。考虑一下这个真实的例子:
"a_crszkvc30LastNameCol",这个词耗费了一个维护工程师小组差不多三天的时间,
才猜出这个词的含义,表示的是一个常数,引用和函数参数,保存了数据库中一个叫做
"LastName" 类型为 Varchar[30] 的字段,并且这个字段还是这个表的主键。
当适当地和"所有的变量都应该是公有的"原则结合起来时,
这个技巧就能够使数千行的代码立即作废!
-
利用 - 人的大脑只能同时处理 7 项信息 - 这个原则的优势。例如,用以上标准写的代码有以下特性:
-
一个赋值语句就带有 14 条类型和名字信息。
-
一个带有三个参数,返回结果中带有 29 项类型和名字信息的函数。
-
寻找一种方法来增强这种极好但又极其简洁的标准。向管理部门和同事施加影响,
建议使用一种能表示星期几的五字母前缀来隔离代码,如 Monam 和 FriPM。
-
用一个中等复杂的嵌套结构就能打败人的短期记忆,尤其是当维护程序员不能
在屏幕上同时看见每个块的开始和结束的时候。
再看匈牙利命名法
: 有关匈牙利命名法接下来一个技巧是"改变一个变量的类型,但是不改变它的名字"。这在从
Win16 :- WndProc(HWND hW, WORD wMsg, WORD wParam, LONG lParam)
到 Win32 WndProc(HWND hW, UINT wMsg, WPARAM wParam, LPARAM lParam) 的移植中常常会用到,
其中 w 表示它们是字(word),而实际上它们常常表示的是长整(long)。当移植到 Win64 的时候这个方法的真正价值才体现出来,
那时候参数都是 64 位长,但是老的 "w" 和 "l" 前缀却永远保留下来。
简化,重用,再循环
: 如果你需要定义一个结构来保存回调数据的话,始终把它叫做 PRIVDATA。每个模块都可以定义自己的
PRIVDATA。在 VC++ 中,具有混淆调试器的优势,这样当你有一个 PRIVDATA 结构,在
watch 窗口中想要展开时,它不知道你需要的是哪个 PRIVDATA,所以它就随便选择一个。
模糊的电影参考
: 用一些象 LancelotsFavouriteColour 之类的常量名字,
而不是 blue,并赋值为十六进制 $0204FB。这个颜色在屏幕上看起来是纯蓝的,
一个维护程序员必须算算(或者使用图形工具)来看看 0204FB 看起来到底是什么样的。
只有非常熟悉 Monty Python 和电影 the Holy Grail,才知道 Lancelot 最喜欢的颜色是蓝色。
如果一个维护程序员不能想到所有 Monty Python 的电影,他或者她就没有资格作为一个程序员。
玩弄颜色
不言而喻,应该使用数字形式的颜色常量,而不是有名字的常量。不幸的是,
大多数熟练的维护程序员都已经知道十六进制编码的颜色值很容易解码。比如 0x0204FB 就是
红 = 02
绿 = 04
蓝 = FB
这种颜色明显几乎就是完全的蓝色。
你所需要的就是使用十进制的数值,132347。没有纸或者计算器的帮助,
任何一个普通人不可能把这个值换算成'蓝'色。额外的好处就是,可以做出一个十进制的颜色值,
但看起来却象是十六进制,比如 808000。一眼扫过去象是半红 + 半绿 = 暗黄色,
但实际上不是十六进制,真正的颜色是 0xc5440(暗青色)。
Netscape 颜色都经过仔细地命名。
例如,papayawhip 是 0xffefd5。为了保持警觉,
把 papayawhip 这个颜色常量定义为 0xff00ff,是一种亮品红色。
享受虚构含糊颜色名字的乐趣,象 algae = 0x556b2f,
而不用 darkolivegreen(暗橄榄绿)。很少人知道 puce(紫褐色)和 teal(凫蓝)是什么颜色,
但却从不承认。利用这一点。
甚至可以为你的后继者布下陷阱。使用精确命名但是很丑陋的颜色。如果后援程序员比较懒,
他会把颜色定义改成清楚一些的,但会留着你原来的颜色名字。