读《编程匠艺—编写卓越的代码》:命名

作者: 思学 | 来源:发表于2014-12-29 09:45 被阅读321次

    刘易斯.卡莱尔(Lewis Carroll):
    “当我选用一个词语时,”矮胖的人以傲慢的语调说道,“它表达的就是我要它表达的意思——不多也不少。”

    一、为什么我们应该恰当地命名

    名字表明了事物的身份,暗示了行为,更易让人记住并识别。

    恰当地命名意味着了解名称就可以了解对象

    二、我们对什么进行命名

    编写代码时,最常命名对象:

    • 变量
    • 函数
    • 类型(class, enum, struct和typedef等)
    • C++命名空间和Java包
    • 源文件

    另外还包括: 状态机的状态、消息传送协议的各个部分、数据库的元素、应用程序的可执行文件等。

    三、好的名称具有那些特性

    1. 描述性的
      尽量做到能望文生义。
    2. 技术上正确的
      只使用字母、数字(不能作开头)、特定字符(下划线);不使用空白(空格、制表符、换行符等);C/C++中不使用str开头带一个小写字母或以下划线开头的全局标识符,以及带命名空间std的标识符;
    3. 符合语言习惯
      了解语言的习惯与约定,如标准库使用一种约定,而Windows Win 32 API使用另一种约定。
    4. 恰当
      根据使用范围,权衡名称长度;注意格调,避免使用blah或wibble等不严肃与foo或bar等古怪的名字。

    四、命名细节

    1. 命令变量
      (a).与现实世界对象相对应的变量,通常使用名词,如GUI应用程序中变量可以用ok_button和main_window;甚至一些概念类的变量,也被赋予名词形式,如elapsed_time或exchange_rate;
      (b). 如果不是名词,变量通常使用名词化的动词,例如count;对于逻辑变量的名称,通常使用一个条件语句形式的名称,例如is_positive, 这样容易判断其值是true还是false。
      (c).为了说明变量是成员变量而不是局部变量或全局变量,常常使用:(1)以下画线作为前缀;(2)以下画线作后缀;(3)以m_作为前缀 三种匈牙利命名法,其中(1)有风险,受到反对;(1)(2)形式不自然。
      (d).一些程序员使用类似_ptr的后缀来修饰指针类型;使用类似_ref的后缀修饰引用类型,这种命名有些多余。
      (e).小范围内,可使用首字母缩略词作变量名。
      (f).将类型名与变量名区分开来,变量以小写字母开头,类型以大写字母开头。
    2. 命名函数
      (a). 函数是一种行为,名字在逻辑上更应该是动词。
      (b).有意义的函数名应当避免使用be、do和perform等只带无用信息的词语。
      (c).始终从使用者的角度为函数命名。如果用户只看到一个函数计算苹果的个数,就不要管函数内部是如何具体实现的,命名这个函数为countApples()吧。
    3. 命名类型
      C语言中typedef命名、定义结构体时,在Java、C++和其他面向对象语言中创建新类型时,需要定义一个好的类型名。
      (a).描述具有状态的数据对象的类,使用名词命名,如Bird;
      (b).仿函数类,使用动词命名;
      (c).接口类,按接口功能命名;
      (d).类型命名中,避免使用class、data、object、type等词。
    4. 命名名字空间
      C++和C#语言中的命名空间和Java语言的包,主要用于对构造分组,还用于防止名称的冲突。
      (a).遵照语言的命名约定,如Java语言定义了一种像互联网域名一样嵌套的包名称的层次结构;
      (b).为命名空间选择名称时,选择反映其内容的逻辑关系的词语。如果内容是某个大型系统的一部分,选择描述这个部分的名称,如操作系统中的UI、filesystem或controls都是很好的名称;
      (c).不要采用暗示命名对象是一个集合的名称——controls_group就是一个不好的名字。
    5. 命名宏
      (a).遵循传统,宏的名称使用全大写字母,并且其他任何地方不再使用全大写方式;
      (b).宏是简单的文本替换工具,应该赋予在其他地方不再出现的独特名字
      (c).使用唯一的文件名或项目名作为宏名称前缀是非常有用的,而且 PROJECTNAME_MY_MACRO比MY_MACRO更安全。
    6. 命名文件
      一些语言对文件名要求严格——Java语言的源文件明必须与其包含的公共类型名相对应;另一方方面,C/C++对文件名无任何限制,但实际上源文件名对编码难度是有实际影响的。
      (a).为了使文件更易命名,每个文件应该只包含单个概念单元,将代码分到尽可能多的文件,同时还能减少文件间耦合和使项目结构更清晰。
      (b).为窗口定义界面的C/C++文件应该命名为widget.h,而不是
      widget_interface.h、widget_decls.h或其他类似的变体。按照惯例,使用匹配文件widget.c或widget.cpp来平衡widget.h吧。
      (c).由于有些系统对大小写敏感有些却无法区分,为了避免出错和考虑代码移植性,采用不同文件名时应当不以大小写不同作为区分,如果可以的话,文件名都使用小写字母吧。
      (d).项目采用混合语言编程,不要同时创建foo.c、foo.cpp、foo.java,这样很混乱。
      (e).为了避免文件同名,向文件名中添加一些路径信息是一种有效手段。

    五、命名的主要规则

    要起一个好名字,做到如下几点:

    • 保持前后一致

    请选择一种命名约定,并坚持使用

    使用一致的命名约定,会易于开发、拓展和维护

    • 利用上下文
      (a).明白命名对象所处范围,尽量把对象放在最小范围中,选择一个在该范围内对上下文有意义的名字;
      (b).每个对象都有类型,但命名时不要再声明类型信息。

    • 使用对你有利的名字
      (a).通过使用公共的前缀,可按相似的名称对对象分组;
      (b).通过函数名称中包含函数参数类型信息,暗示输入参数或输出参数。

    六、总结

    《诗篇》(psalms):
    我将寄希望于你的名,这名本为美好

    好的名称不仅仅是审美上的需要,还传达了关于代码结构信息,还是不可或缺的协助理解和维护的工具

    七、建议

    不要创建如下特征的名称:

    • 含义模糊
      首字母缩略词和简写太随意,单个字母太神秘
    • 啰嗦
      不要创建the_number_of_apples_before_I_started_eating这样的变量名
    • 不准确或使人误解
      一个对象与列表无关,就不要起widget_list之类的名
      不要拼写错误,如把ignoramus写成ignoramous
    • 有歧义
      不要使用有多种解释的名称
    • 太做作
      有趣的小缩写、自作聪明的简写和对数字的解释性使用都应该避免。
      对于经验少的人,internationalization的常见缩写i18n是不够清晰的。

    八、内容相关

    匈牙利命名法
    由于它的创始人程序员Charles Simonyi是匈牙利人和变量名看起来像是匈牙利语书写,被称为匈牙利命名法。最初从Microsoft公司传出,后被发展成多种匈牙利命名法;现在是一种很受争议的命名法,因为它的基本原则是:变量名=属性+类型+对象描述,而在名称中添加类型是一种冗余。

    大写字母约定

    • 20世纪70年代早期在Smalktalk第一次使用的camelCase型,现在广泛使用于Java语言库(一般用于类成员名)和许多C++代码库;
    • .NET、Windows API以及Java类名使用的ProperCase(PascalCase)型
    • C++标准库和GNU Foundation中使用的using_underscores型

    文件后缀
    选择后缀也是文件命名的一部分。Java的编译系统要求文件名以.java作为结尾;但C/C++对后缀无要求。但我们应当使用普遍的约定,如C++实现文件采用.C、.cc、.cpp、.cxx和.c++常见后缀;头文件使用.h或.hpp后缀。

    相关文章

      网友评论

        本文标题:读《编程匠艺—编写卓越的代码》:命名

        本文链接:https://www.haomeiwen.com/subject/dkxztttx.html