Make Correct Code Look Correct

这是以前从一本书上看到的一篇文章,在网上也找到了英文原版http://www.joelonsoftware.com/articles/Wrong.html

这里仅仅想用一个简单的例子把原文思想再复述一下,再掐个头去个尾,添点油加点醋。

匈牙利命名法

貌似匈牙利命名法挺有争议的,说实话,我也没怎么感受到它的好处。像C语言,编译器会帮我们检查类型,又何必再在名字上画蛇添足呢;名字前缀上类型,敲代码的时候就觉得很烦,而且编辑器的自动补全功能会跳出来一大堆候选名字,因为相同类型变量的开头字母都相同。

会不会是我们的用法有问题呢?

例子

假设有这样一个系统,从界面取得用户输入的一个书名,然后从数据库查出该书的相关信息。

要查询数据库,就要用输入的书名字符串BookName生成一条SQL查询语句。但首先要把BookName中含有的特殊字符转义掉:

Escape(BookName);

另外,系统可能还会把每天的查询记录写到一个日志文件中。这就要用到转义前的BookName了,需要

Unescape(BookName);

如果代码量小,这样写问题不大。但在代码量很多的情况下,假如要在代码中间加入一条语句,打印有关BookName的日志消息,问题就来了。这个BookName到底有没有被转义过呢?可能作者都晕头转向了。所以,这种“原地”转义不可取。(“原地”,就是在原字符串上做操作)

如果把转义得到的新字符串赋给另外一个量呢?

NewBookName = Escape( BookName);

嗯,问题解决一部分了。至少我知道,NewBookName是转义过的,BookName是没转义过的。但要是换一个人来维护,估计又搞不太清了。

问题的最终解决办法是,把转义前的字符串看做是一种数据类型,转义后的字符串看做是另一种数据类型。不过在编译器看来,它们的类型没有区别,都是字符串。所以要靠程序猿自己检查类型了,如何写才能把类型正确性直观地表现出来呢?就要在命名上做文章。

把转义前的类型用us表示(unsafe),转义后的类型用s表示(safe)。从界面读到的字符串我们存放在UsBookName中,转义后的字符串存放到SBookName中。这样什么时候用哪个变量就不会搞混了。甚至还可以给转换函数加上类型,把escape命名成SEscapeFromUs,表示从us类型转为s类型,调用时,

SBookName = SEscapeFromUs(UsBookName);

这样,至少从形式上可以判断出代码没有问题。

这才是匈牙利命名法的本意。它使那些仅在语义上有微小区别的变量,通过命名约定,从形式上加以区别,使得代码的正确性一目了然,而不必去联系上下文理解,大大降低了代码之间的耦合性。

好像有点故弄玄虚了,其实就是提醒我们要注意命名,名字要清晰、全面地表达所指对象的含义罢了~:)

你可能感兴趣的:(Make Correct Code Look Correct)