细节之中自有天地,整洁成就卓越代码。
只要我们写的代码有人读,那么我们就有必要将代码整理干净,看起来清清爽爽。也
许你是一个初学者,像鲍勃大叔说的低水平编码者为代码猴子,上蹿下跳,自以为领
略了编程的真谛,可惜,当我们抓着几个酸桃子,得意洋洋地坐到树枝上,却对自己
的混乱熟视无睹。那堆“可以运行”的乱麻程序,就在我们的眼皮底下慢慢腐坏。
一、整洁代码
首先,代码是机器可以执行的细节程度,我们永远无法抛弃必要的精确性——所以代码永存。而好的代码的重要性不言而喻,糟糕的代码犹如密布的灌木、瀑布暗藏的沼泽,混乱,烂,导致团队生产力持续下降,甚至严重到毁掉一家公司。花时间保持代码整洁不但有关效率,还有关生存。那么,我怎么才能写出整洁的代码呢?
我喜欢优雅和高效的代码。代码逻辑应当直接了当,叫缺陷难以隐藏;尽量减少依赖关系,使之便于维护;依据某种分层战略完善错误处理代码;性能调至最优,省得引诱别人做没规矩的优化,搞出一堆混乱来。整洁的代码只做好一件事。–Bjarne Stroustrup,C++语言发明者,C++ Programming Language(中译版《C++程序设计语言》)一书作者
借用美国童子军一条简单的军规,应用到我们的专业领域:让营地比你来时更干净。
二、有意义的命名
-
名副其实
问题不在于代码的简洁度,而是在于代码的模糊度:即上下文在代码中未被明确体现的程度。
int d; //消逝的时间,以日计
名称d什么也没说明。它没有引起对时间消逝的感觉,更别说以日计了。我们应该选择了
计量对象和计量单位的名称:
int elapsedTimeInDays;
int daysSinceCreation;
- 避免误导
避免留下掩藏代码本意的错误线索。提防使用不同之处较小的名称。
真正可怕的例子,用小写字母l和大写字母O作为变量名,看起来是“壹”和“零”。 - 做有意义的区分
犯错的代码例子:
getActiveAccount();
getActiveAccounts();
getActiveAccountInfo();
程序员怎么能知道调用哪个函数呢?
要区分名称,就要以读者能鉴别不同之处的方式来区分。
- 使用读得出来的名称
例如函数名genymdhms(生产日期,年、月、日、时、分、秒),傻乎乎的自造词,而非恰当的英语词。改成generationTimestamp生产时间戳可要好多了。 - 使用可搜索的名称
找到MAX_CLASSES_PER_STUDENT很容易,但是找到数字7就麻烦了。长名称胜过短名称,搜得到的名称胜过自造编码代写的名称。 - 避免使用编码
把类型或作用域编辑进名称里,徒然增加了解码的负担。匈牙利语标记法,成员前缀,m_前缀,可以使用高亮或颜色标出成员变量。如果接口和实现必须选一个编码,宁肯选择实现。 - 避免思维映射
不应当让读者在脑中把你的名称翻译成为他们熟知的名称,明确才是王道。 - 类名
类名和对象名应该是名词或名词短语,类名不应当是动词。
方法名应当是动词或动词短语。 - 别扮可爱
不要用俚语,太耍宝的,幽默的来命名。言到意到,意到言到。 - 每个概念对应一个词
给每个抽象概念选一个词,并且一以贯之。例如,fetch,retrieve,和get来给在多个类中的同种方法命名,怎么能记住呢? - 别用双关语
避免将同一单词用于不同目的。 - 使用解决方案领域名称
只有程序员才会读你的代码,所以尽量用专业是计算机科学术语、算法名、模式名、数学术语。 - 使用源自所涉问题领域的名称
如果不能使用解决方案领域的名称,那就采用与问题领域更贴近的代码名字。 - 添加有意义的语境
你需要有良好命名的类,函数或命名空间来放置名称,给读者提供语境。给名称添加前缀是最后一招了。设想你有名为firstName、lastName、street、houseNumber、city、state和zipcode的变量,搁到一块就很快推断出是一个地址,如果把state单独放在一个地方,你还能推断出来吗?可以addrFirstName、addrLastName来提供语境。 - 不要添加没用的语境
只要名称足够清楚,就要比长名称好。MAC地址、端口地址和web地址相区别,考虑用PostalAddress、MAC和URI。 - 最后的话
试试上面的规则,看看代码的可读性是否有所提高,如果你是在维护别人的代码,使用重构工具来解决问题。效果立竿见影,而且会持续下去。