『No24: 编写可读代码的艺术(1)』

987654321.jpg

大家好,我叫谢伟,是一名程序员。

除了本职工作,还有点幻灯片演示设计的爱好。随着编写代码的增多,制作的的幻灯片越来越多,越来越意识到,很多事物都存在相通性。

这就解释了为什么有很多人,能擅长多个领域。难道不是因为掌握了底层本质的东西吗?

为什么琅琅上口的口头禅能传播的更广泛?

为什么好的文案既精简又足够引起用户的注意?

为什么谣言也传播的更为广泛?

是的,他们一定都准确的抓住了用户的心理。

本文结合一些简易的设计规范来解释:编写可读代码的艺术。

《写给大家看的设计书》一书中全文在诠释设计的四个规范:亲密、对齐、重复、对比。
《编写可读代码的艺术》一书中全文在诠释编写可读代码的艺术:让人易于理解。

是的,市面上存在很多很优秀的设计师,设计的作品,既足够精美,又让用户秒懂。好的设计者一定深谙心理学。

编写代码,实质是在梳理逻辑,为了完善整个逻辑流程,我们借用编程语言的变量、函数、流程控制、循环、注释、方法等串接起来,完善一套系统的逻辑。

为了完善这套逻辑,我们借助了许多工具:设计方法、架构设计、项目组织等。

意识到没有,代码的好坏一定程度上可以从逻辑层面评判。

  • 符合逻辑,不一定是最优的代码
  • 不符合逻辑,一定不是好的代码

从这层面来看,梳理逻辑极为重要,逻辑通了,剩下的就是实现了。

逻辑的串接靠的是编程语言的变量、函数、流程控制、循环、注释等。

本文从这些层面讲述,如何编写可读代码。

0. 规范

绝大多数的人,不会从零完整的完成一个复杂的项目,大多是团队共同合作,完成一个大的项目。

这个时候,假如你是中途参与进来。你在实现逻辑的时候,你是照着自己的逻辑来还是依照团队的风格来。

比如项目组织,命名等...

依照团队的风格来

尤其针对复杂的上线的项目,完整的理解整个项目都存在困难,这个时候,风格统一尤其重要。

是的,这个时候,风格一致性重要,当然具体的实现逻辑,还是应该遵从易于理解这个大方向。

1. 编程语言规范

准则:坚持编程语言的风格

每门编程语言,都存在一定的规范,比如 Python 采用的下划线的变量命令规则,Go 则采用驼峰式的变量命令规则等。

这个时候,编程语言的整体规范需要遵从。

大家可能会多参考 google 出品的各种编程语言规范。方向没错。

2. 命名

  • 变量
  • 函数
  • 方法

准则:易于理解

如何做到易于理解:

  • 专业的单词:使用领域内的单词
  • 避免空泛的名字
  • 具体的名字
  • 变量名带上更多细节
  • 不使用令人误解的名字
  • 布尔值命名
  • 不建议使用的单词

2.1 领域内的单词

这个和项目相关,比如系统是个智慧零售后台,那们领域内单词多是:顾客、商品、商铺、店员、店长、价格等。

  • customer
  • produce
  • shop
  • shopLeader
  • price

2.2 避免空泛的名字

变量的命名一般要赋予一定的意义,极少情况下可以使用没有什么意义的单词。比如最常见的:


var (
    numberOne int
    temp int
    numberTwo int
)
tmp = numberOne
numberOne = numberTwo
numberTwo = tmp

再比如:

var i int

for i=0;i<10;i++{
    fmt.Println(i)
} 

这种没什么意义的单词,一般适用于局部作用域。

尽量少用。

2.3 具体的名字

完成什么任务就使用什么单词。一般变量使用名词居多,函数使用动词开头居多。

函数多用动词,变量多用名词

比如:

var toString = func(){}

var serverLoop = func(){}

var pages int 

var userName string

2.4 带上更多细节

一般命名不建议过长,也不建议过短,那多长,多短合适呢?

最长三个单词的长度吧

如何带上更多的细节。

  • 尝试使用后缀
  • 尝试使用单位
  • 尝试指向具体的细节

比如:

var timeIntervalMs

var lengthCm

var delaySecs

var sizeMb

var maxKbps

var degreesCw

var numberMax

var numberMin

var numberFirst

var numberLast


赠送几组对仗的后缀:

  • max/min
  • first/last
  • begin/end
    ...
ServerCanStart() 不如 CanListenOnPort()

2.5 不使用令人误解的词

比如:Filter 在数据库操作中容易使用这个单词,这个单词没有带上更多的细节,实质上在使用的过程中,还是需要查看编写的SQL 语句等才能知道具体的过滤细节。整体思考多了几步。不易让人理解。

建议多读几遍自己命名的单词

2.6 布尔值

提到布尔值,因为就存在两种结果。所有,一般使用是否这样意思的词。

比如:


var (
    ok bool
    notOk bool
)

var (
    is bool
)

var (
    has bool
)

var (
    found bool
)

var (
    should bool
)


var isCompany = func(){}

var isVip = func(){}

var hasSpace = func(){}


2.7 不建议使用的单词

  • get
  • read
  • util

恰恰这几个单词,在写代码中最容易使用。选择替代方案。

赠送一波动词:

- send

deliver、dispatch、announce、distribute、route

- find

search、extract、locate、recover

- start

launch、create、begin、open

- make

create、setUp、build、generate、compose、add、new

3. 设计

一份好的幻灯片演示设计需要考虑什么?

  • 符合场景的配色,确定原始基调
  • 符合场景的事物,借用来表达观念
  • 统一整体风格
  • 对齐、重复、亲密、比较

看到没,幻灯片演示设计,强调场景化,选择适合场景的主体和配色,比如党政风格,当然选择国旗色;比如学术答辩,当然选择蓝色;比如手机发布会,当然使用暗黑科技风格...

所以代码也需要场景化,选择符合场景的单词等

这里以设计的四个规范类比代码的组织。

3.1 对齐

编程语言为什么强调缩进?难道不是为了阅读代码的人更容易看懂代码吗?写代码的人更容易组织代码吗?仅仅是设计者为了好玩?

当然不是。

举例:编写web路由和控制器

// student.go

func Register(r *gin.Group) {
    r.POST("/v1/api/students", PostHandler)
    r.GET("/v1/api/students/:sid", GetHandler)
    r.PATCH("/v1/api/students/:sid", PatchHandler)
    r.PUT("/v1/api/students/:sid", PutHandler)
    r.DELETE("/v1/api/students/:sid", DeleteHandler)

}
  • 放眼望去,确实知道实现什么任务
  • 风格统一
  • 整整齐齐

这个例子可能解释对齐,不够友好。

再举个例子:

CheckFullName("No Such Guy","",  "not match found")

CheckFullName("John",     , "",  "more than one resule")

3.2 重复、亲密、比较

当然,作为程序员,最应该避免的其实就是写重复的代码,一般的做法往玩是提炼,将重复的抽象出一个函数之类的。这里的重复,是风格的统一

// teacher.go

func Register(r *gin.Group) {
    r.POST("/v1/api/teachers", PostHandler)
    r.GET("/v1/api/teachers/:tid", GetHandler)
    r.PATCH("/v1/api/teachers/:tid", PatchHandler)
    r.PUT("/v1/api/teachers/:tid", PutHandler)
    r.DELETE("/v1/api/teachers/:tid", DeleteHandler)

}

可以结合比较下 student.go 和 teacher.go

这样的组织方式,讲道理,并不太会给阅读代码的人带来太多的认知负担。

  • 一致的顺序
  • 始终一致的使用,使用户其实阅读一个,类似的都能秒懂

3.3 留白

设计领域页面的设计,并不强调内容越多越好,恰当的在页面上留有空白,使整体设计有呼吸感。

那编程如何实现留白?

  • 恰当的换行,使相似的内容更紧凑
  • 提取,使用方法来组织不规范的东西
  • 代码分段

假如你一个函数需要写 100 多行,不好意思,我可能建议你,不要这么做。

  • 拆分,逻辑梳理、提取方法
  • 尽量维持最长 30~50行左右(这样使屏幕能装载下,一次就能完成的阅读整个函数的逻辑)

4 注释

准则:帮助阅读代码的人对代码了解的和写代码的人一样多

  • 什么时候不需要注释
  • 什么时候需要注释

4.1 什么时候不需要注释

是的,前文的一系列准则,命名啊之类的,是内容,也是注释,通过阅读变量、函数名等就了解了代码完成的任务。

这样的地方不需要注释,因为显而易见,从代码本身就能推断事实。

有时候可能需要考虑是不是命名不好,导致需要注释,这个时候,命名优于注释。

给不好的代码注释,和在错误的路上持续努力一样令人可怕。

4.2 什么时候需要注释

  • 关键点
  • 缺陷点
  • 常量
  • 全局注释
  • 总结性注释

关键点

有些时候,仅仅靠之前的“表面工作” 已经不能完全能够满足让人易于理解。这个时候需要在关键点添加注释。

缺陷点

是的,承认自己的代码写的不是最优的,仅仅只是实现,还存在更优的办法,所以需要在有缺点的地方加上注释。

常量:(各编程语言建议常量大写)

给常量注释,赋予了更多的意义。

比如:


NUMTHRADS = 8 // as long as it is >= 2 * number_processors, that is good enough.

好,假如你正在优化代码,看到这注释,是的,你知道该如何调整了。

全局注释

一般在文件开头,表明文件内代码完成的任务。

总结性注释

一般函数开头,表明函数代码完成的任务。

其他

润色语句。言简意赅由于冗长的解释。(这些貌似对文字功底要求高点)

5. 总结

从“表面”给出编写可读代码的建议,下一篇介绍从流程、循环、抽象、组织代码等角度谈编写可读代码的建议。

下节再会,我是谢伟。

谢谢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容