如何代码命名


  1. 前言
  2. Level 1: 坏味道
  3. Level 2: 命名技巧
    1. 增加词汇量
    2. 更好的命名方法
  4. Level 3: 领域语言(Domain language)

There are only two hard things in Computer Science: cache invalidation and naming things. —— Phil Karlton

前言

开发人员习惯性的对设计、架构、微服务夸夸其谈,却很少关注设计、架构如何完完整整的落地到代码本身。架构和设计固然重要,代码并非不重要。正如 Robert C.Martin 所言:“代码即设计”。透过好的代码,就能看到其背后精美的设计。

好的代码,第一步是为每一个类、函数、变量起一个好的名字。可惜的是,大多数人对于如何起一个好名字不得其法。毕竟严格上来说,命名并非计算机科学的范畴。好的命名一个词就可以简单、形象、直观表明其功用甚至原理,例如:

  • SYN flood:洪水一样的SYN请求

  • Pipeline:管道一样传输数据、依次且单向

design-thinking-process

以上还只是问题解决域,还不是最难的。最难的是,在实际研发中,还要面对问题分析域。如果你的思路结构、层次不清晰,抽象出的各种状态不正交,相互重叠,交差,此时再想起出比较好的名字,则回天乏术;如果你不知道一个事物应该叫什么,你就不可能知道它是什么(A Rose by Any Other Name Will End Up As a Cabbage),所以命名的过程也是整理思路的过程。

根据过往的经验总结,可以将命名分为三个Level,前两个 Level 覆盖 Solution Space 的困境,最后一个 Level 覆盖 Problem Space 的困境

  • Level 1:坏味道,嗅出坏味道才能意识到需要改变
  • Level 2:命名技巧,一些简单的命名技巧,明白有哪些渠道可以改进
  • Level 3:领域语言,命名的道,命名是可以系统化的从业务过渡到研发。

Level 1: 坏味道

  • 无意义的命名

    i.e. datainforecord

  • 抽象的命名

    i.e. dataobjecthelpertoolmanagerprocessorhandlermakerutilconfthinginfoamountdetailsdoexecuteperformoperatemanagehandle

    不够精确,毫无疑问,你确实命名了数据和对象,但即使没有此模糊的名称你也早知道的。将 data 重命名为更具描述性的名称,以标识数据

  • 简称

    i.e. mod

    mod 像是某个单词的简称,你可能无法确认到底是 modemodule

  • 含糊

    i.e. Manager

    命名模糊,谁知道经理到底是干什么的?可以更有意义的替代方案,如:牧民(Herder)、主管(Supervisor)、策划人(Planner)、建筑商(builder

  • 多个单词

    i.e. company_person 代表公司人员

    重命名 company_personstaff 更为合适,或者更新一步 employeedirector

  • 被动语态

    i.e. PlanEvents

    重命名 PlanEvents 为主动语 EventPlanner 更好,或者更进一步 Scheduler

Level 2: 命名技巧

增加词汇量

命名只是写作的一部分,主要是词汇。你可能还记得学习外语的一部分就是学习词汇。不用学外语是利弊并存之事。

  • 阅读开源、基础库代码
    • 例如:Linux 内核、C++ STL 库 等等
  • 查找业务关联概念
    • 例如,库存单位:sku ( Stock Keeping Unit );搜索简称:qv (Query View Count)

更好的命名方法

  • 遵从惯例、标准

    不要使用identifier,而是使用业界惯例 id 作为唯一标识命名。类似的:

    • ptrpointer的缩写;
    • ijk 常常是完美的循环计数变量命名。
    • sizecapacityresizereservepushpoptopback,作为容器的接口,久经考验。要自定义容器不应该使用 GetSize 等命名。
  • 遵从约束

    • 语言约束:例如,Go 语言 使用 驼峰 风格,代码中就不要使用C语言的 大写下划线连词 风格
    • 团队约束:对同一个概念,团队内已经有对应的称呼,应该遵从,而是不是任性夹带私货,例如:直播中(ongoing vs living),已经命名为 ongoing ,要么替换为 living;就全部替换掉,要么继续使用 ongoing,虽然后者更确切。
    • 框架约束:使用 Shopify/sarama 作为 kafka 的 客户端就应该使用ConsumerConsumerGroupConsumerGroupHandler,命名三个层级,而不是自撰 三个层级:DaoConsumerProcessor
  • 对齐、对称

    对齐: Golang 标准库包名,httptest、httputil、httptrace

    对称:典型的对称,producer/consumerbegin/endcreate/destorydestination/sourceget/releaseincrement/decrementinsert/deletenext/previousold/newold/newopen/closeput/getshow/hidestart/stoptarget/source

Level 3: 领域语言(Domain language)

人对名字的反应是潜意识的…所以如果对一个名字有疑惑,可能很难确切地表达原因。我们的设计系统命名应该符合预期。… 但是谁的期望?所有利益相关者,系统的利益相关者,包括但不限于:

  • 产品经理
  • 开发(前端、后端、客户端)
  • 测试
  • 用户

代码应该自动使用与业务或领取模型相同的名称。例如,如果一个旅游企业使用 “venue” 作为咖啡馆、酒店和旅游景点的通用名称,那么在代码中使用 “place” 是一个坏主意

  • 其一,因为使用两种不同的语言,使得沟通变得更复杂
  • 其二,如果一个词汇,产品经理和用户等不理解软件开发同学的都能直观的理解,那么此命名将是一个好的名字
  • 其三,将代码命名与领域模型关联起来,所有命名跟业务是契合的
  • 其四,随着需求迭代,打磨领域模型的同时,可以保证命名随之重构符合语义,保持常新

使用领域语言统一开发流程,可以从根本上解释命名来源以及合理性。相比一般的技巧,是系统的有理论支撑的。如果技巧是工程派的产出,那么领域语言指导命名就像是学院派的产出。

具体如何在项目中实施DDD,后续详解。

本文作者:cyningsun
本文地址https://www.cyningsun.com/07-04-2020/how-to-naming-things.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!