There are only two hard things in Computer Science: cache invalidation and naming things. —— Phil Karlton
前言
开发人员习惯性的对设计、架构、微服务夸夸其谈,却很少关注设计、架构如何完完整整的落地到代码本身。架构和设计固然重要,代码并非不重要。正如 Robert C.Martin
所言:“代码即设计”。透过好的代码,就能看到其背后精美的设计。
好的代码,第一步是为每一个类、函数、变量起一个好的名字。可惜的是,大多数人对于如何起一个好名字不得其法。毕竟严格上来说,命名并非计算机科学的范畴。好的命名一个词就可以简单、形象、直观表明其功用甚至原理,例如:
SYN flood:洪水一样的SYN请求
Pipeline:管道一样传输数据、依次且单向
以上还只是问题解决域,还不是最难的。最难的是,在实际研发中,还要面对问题分析域。如果你的思路结构、层次不清晰,抽象出的各种状态不正交,相互重叠,交差,此时再想起出比较好的名字,则回天乏术;如果你不知道一个事物应该叫什么,你就不可能知道它是什么(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.
data
、info
、record
抽象的命名
i.e.
data
、object
、helper
、tool
、manager
、processor
、handler
、maker
、util
、conf
、thing
、info
、amount
、details
、do
、execute
、perform
、operate
、manage
、handle
不够精确,毫无疑问,你确实命名了数据和对象,但即使没有此模糊的名称你也早知道的。将
data
重命名为更具描述性的名称,以标识数据简称
i.e.
mod
mod
像是某个单词的简称,你可能无法确认到底是mode
或module
含糊
i.e.
Manager
命名模糊,谁知道经理到底是干什么的?可以更有意义的替代方案,如:牧民(Herder)、主管(Supervisor)、策划人(Planner)、建筑商(builder)
多个单词
i.e.
company_person
代表公司人员重命名
company_person
为staff
更为合适,或者更新一步employee
或director
被动语态
i.e.
PlanEvents
重命名
PlanEvents
为主动语EventPlanner
更好,或者更进一步Scheduler
Level 2: 命名技巧
增加词汇量
命名只是写作的一部分,主要是词汇。你可能还记得学习外语的一部分就是学习词汇。不用学外语是利弊并存之事。
- 阅读开源、基础库代码
- 例如:Linux 内核、C++ STL 库 等等
- 查找业务关联概念
- 例如,库存单位:
sku
( Stock Keeping Unit );搜索简称:qv
(Query View Count)
- 例如,库存单位:
更好的命名方法
遵从惯例、标准
不要使用
identifier
,而是使用业界惯例id
作为唯一标识命名。类似的:ptr
为pointer
的缩写;i
、j
、k
常常是完美的循环计数变量命名。size
、capacity
、resize
、reserve
、push
、pop
、top
、back
,作为容器的接口,久经考验。要自定义容器不应该使用GetSize
等命名。
遵从约束
- 语言约束:例如,Go 语言 使用
驼峰
风格,代码中就不要使用C语言的大写下划线连词
风格 - 团队约束:对同一个概念,团队内已经有对应的称呼,应该遵从,而是不是任性夹带私货,例如:直播中(
ongoing
vsliving
),已经命名为ongoing
,要么替换为living
;就全部替换掉,要么继续使用ongoing
,虽然后者更确切。 - 框架约束:使用 Shopify/sarama 作为 kafka 的 客户端就应该使用
Consumer
、ConsumerGroup
、ConsumerGroupHandler
,命名三个层级,而不是自撰 三个层级:Dao
、Consumer
、Processor
- 语言约束:例如,Go 语言 使用
对齐、对称
对齐: Golang 标准库包名,httptest、httputil、httptrace
对称:典型的对称,
producer
/consumer
、begin
/end
、create
/destory
、destination
/source
、get
/release
、increment
/decrement
、insert
/delete
、next
/previous
、old
/new
、old
/new
、open
/close
、put
/get
、show
/hide
、start
/stop
、target
/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 许可协议。转载请注明出处!