最近挑灯夜读了Kent Beck大侠的Smalltalk Best Practice Patterns Volumn 1: Coding,又重新开始注意命名了,在Intention Revealing Selector里面举了一个例子linerSearchFor -> searchFor -> includes,作者觉得后面的名字要比前面好,作者教的一个方法就是想像这个东西的另外一个实现方式,而我觉得这种方式并不太有效,对我。
我最近在折腾FxCop的自定义Rules,从中悟出了一个Kent Beck自己真正使用的命名方式:基于上下文来命名。故事是这样的:
FxCop有一个函数Check(xxxx)返回一个ProblemCollection,那么如果你测试,你就要这样写:Assert.IsNotNull(rule.Check(xxx)),而你这样读就就会觉得很怪,这样的代码不成一个句子,Check is not null是不通的,Check是一个动词,在这里。而我重新命名了一下得到一个更好的名字ProblemsOf,这个名字孤立来看,似乎没什么意思,但是如果你把它放回单元测试的上下文,就变成:Assert.IsNotNull(ProblemsOf(xxx)),problems is not null还是比较说得通的。从中得出的经验就是:你永远不能孤立地去命名,这样你永远都命不好,方法就是把这个名字放在它被用到的上下文里面去看它是否能够和这个上下文无缝的结合起来,符合语法,符合习惯,这样你的代码才能向一篇文章那样易读,因为你的脑袋不需要去填充这些名字和名字之间的gap。
回到Kent Beck自己的例子Assert.IsTrue(a.searchFor(foo))当然不能符合上下文,而Assert.IsTrue(a.includes(b)),就非常符合上下文了。故此这个名字好。
你并不是为了读者能够更容易地理解这个函数的实现而给它命名,你是为了让读者更容易理解函数如何组合在一起而命名,因为后者更难理解。
【作者: RonaldMatt】【访问统计:】【2007年05月29日 星期二 11:10】【注册】【打印】
你可以使用这个链接引用该篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=6299477