这一周博主阅读了《代码大全2》第11章至第13章,第三部分——"变量"就结束了,第四部分作者将转入语句的讨论。

第十一章作者详细阐述了变量名的有效命名规则,第十二和十三章则简略介绍了使用各种数据类型时的注意事项。在这篇博客中我主要会在变量名命名和全局变量的使用上谈谈自己的读书心得。

变量名的力量

我们先来谈谈命名规则的必要性。为什么要有命名规则?会破坏创造性和程序质量吗?这一点我在上一篇读书笔记中已经以最近结对编程为例提到过了。对程序质量的实质约束往往来自高层设计,有效的标准其实是可以提高程序质量和效率的。具体来说,命名规则具有以下几大优势:

1.增强程序的自解释性(self-explanatory),使我们隔一段时间后再看自己写的程序时可以快速读懂代码、回忆起当时自己的思路;团队协作中,当开发者需要接手修改和维护其他人编写的代码时,不至于一头雾水。这一点对我们接下来的团队项目有重要的指导意义。

2.按规矩行事可以让我们把精力集中在其他更需要充分考虑的地方(比如算法、类的设计等等)。

3.使相关变量之间的关系更加清晰。比如说employeeIDNumber、employeeAddress、employeeSalary显然比IDNumber、address和salary看起来更紧密相关。注意到,假如在支持类的编程语言中我们定义一个employee类,将IDNumber,address和salary设为可访问的数据成员时,就可以在外部调用时用employee.IDNumber、employee.address、employee.salary来表达。从这一点我们可以看出,好的命名规则还可以弥补编程语言的不足。

自从开始有意识地用适合自己阅读、理解的方式给变量精细命名,我常常为一些中间变量的命名踌躇良久。一个好的变量名应该是可读、易记、恰如其分的。对变量的描述即是最佳的变量名,但是太长了不实用;短的变量名适用于作用域小的变量,如普通的循环计数器。我在书中选取了一些让我感觉比较有帮助的建议来分享一下:

1.计算限定词如total、sum、min、max、average、pointer等等统一放在前方或后方,一致性可以降低犯错的几率。

2.多用对仗词,比如最常见的min/max、begin/end、next/previous、last/current等等,这些对仗词是要放在合成词的前面部分还是后面部分,也要有一个统一的约定。

3. 循环变量、状态变量、临时变量、布尔变量、枚举变量在命名方法上有差异。临时变量不要用temp表示,稍微在temp后面添加确切信息,或者舍弃temp给出更准确的描述。布尔型变量不要用status,因为不管返回true还是false都看不出其对当前的过程有什么具体含义,用isDone, isError, success会使变量的含义更确切。

4.具名常量用大写和下划线的组合,可以描述得尽量细致一点。

5.有时候囿于编程语言对变量名长度的限制,我们不得不起短名字,缩写也涉及到很多技巧,基本上是服务可读性这一点,比如说使用列在字典里面的缩写、去掉一些非前置元音,像是source变成src, computer变成cmptr, 当然没必要去掉所有元音,比如xPosition缩写成xPos比xPst更好理解一些。

书中还有关于非正式命名规则的一个小节,适用于短小的、用完即弃的程序。我个人觉得没有必要了解,因为我们需要在日常编程实践中培养好的命名习惯,并探索高效的命名规则,才可能在实战中保证变量名的质量。

慎用全局变量

全局变量的风险是程序员的常识,不过在实际编程过程中我们往往还是会和全局比变量打交道。编写汇编程序的时候,定义在代码段的变量都是全局变量,又比如我使用Keil为单片机芯片编写程序时,涉及到中断操作时也常常会用到全局变量。然而在用面向程序和面向对象语言编程时,使用全局变量还是谨慎一些。我们来看看全局变量有哪些缺陷:

1.违反了模块化和信息隐藏的原则,增大了所需管理的复杂度。如果一个子程序和用到了全局变量,那么在编写、调试这个子程序的时候还得同时考虑到这个全局变量而不仅仅是这个子程序本身。

2.全局数据会阻碍代码重用。想象一下你需要使用在另一个文件中定义的类或子程序,而这个类或子程序又使用了定义在那个文件的全局变量,那么是否需要在当前文件中重复定义这个全局变量?定义之后能保证这个变量的值按照你所期待的维持或变化吗?

3.多线程编程中的代码重入问题:多线程代码运行过程中有可能全局数据在同一个程序的不同拷贝之间共享,这种情况下必须确保全局变量还保持有确切的含义。

全局变量一般适用于一些在概念上用于整个工程的数据以及在程序的每一个子程序中都需要用到的数据或变量,编程语言不支持具名常量时也可以用全局变量来模拟,不过往往这些目标都可以通过其他更好地方式来达成。如果迫不得已一定要使用全局变量,可以尝试用以下方法来降低风险:

1.为全局变量选取一个与其他变量不同的、更醒目的命名方式。

2.列出全局变量的清单,标注具体功能,在调用全局变量的地方适当注释作为提示。

3.不要用全局变量来存放中间结果。

《代码大全2》读书笔记 Week8的更多相关文章

  1. 代码的未来读书笔记<二>

    代码的未来读书笔记<二> 3.1语言的设计 对Ruby JavaScript Java Go 从服务端client以及静态动态这2个角度进行了对照. 这四种语言因为不同的设计方针,产生了不 ...

  2. 《第一行代码 android》 读书笔记:找出当前界面对应的Activity

    在android开发中找出当前界面对应的Activity,步骤如下: 新建一个BaseActivity继承自Activity,然后在BaseActivity中重写onCreate()方法,通过getC ...

  3. 《Linux命令行与shell脚本编程大全》- 读书笔记1 - 基本的bash shell 命令

    这本书买了好久了,除了刚到手的那几天翻看了一下以外,竟然到今天都没有看过.突然想要写一个shell脚本,发现什么也不会,是时候开始学习了,今天先把最简单的一章再看一遍顺便做一些笔记,明天继续后面的! ...

  4. 【代码大全2 学习笔记】ADT 抽象与封装

    ADT abstract data type 抽象数据类型 要理解面向对象编程,就要先理解ADT这个概念.不懂ADT的程序员开发出来的类只是名义上的"类"而已--只是单纯的把一些相 ...

  5. 《Linux命令行与shell脚本编程大全》- 读书笔记3 - 理解shell

    当用户登录终端的时候,通常会启动一个默认的交互式shell.系统究竟启动哪个shell,这取决于用户配置.一般这个shell都是/bin/shell.默认的系统shell(/bin/sh)用于系统sh ...

  6. 《Linux命令行与shell脚本编程大全》- 读书笔记2 - 更多的bash shell命令

    更多的bash shell命令 想检测进程,需要熟悉ps命令的用法.ps命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息.默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户 ...

  7. 《Linux命令行与shell脚本编程大全》读书笔记

    第一章:初识Linux 1.linux可划分为四个部分:内核.GNU工具.图形化桌面环境.应用程序 2.内核主要负责:系统内存管理.软件程序管理.硬件设备管理.文件系统管理 3.内核的系统内存管理,有 ...

  8. 《代码大全》阅读笔记-33-个人性格(personal character)

    很多好的编程做法都能减轻你的大脑灰质细胞(指脑力)的负担. 将系统"分解",是为了使之易于理解("设计的层次"). 进行审查.评审和测试正是为了减少人为失误.如 ...

  9. 《代码大全2》读书笔记 week 7

    博主终于继续更<代码大全2>了 (*´・ω・`)⊃,课上老师一再强调读书笔记要写出自己的心得不能简单摘抄,所以我现在基本上只会写一下自己在阅读过程中印象深刻或者有发散思考的地方,字数可能 ...

随机推荐

  1. Netty 粘包 拆包 | 史上最全解读

    Netty 粘包/半包原理与拆包实战(史上最全) 疯狂创客圈 Java 聊天程序[ 亿级流量]实战系列之13 [博客园 总入口 ] 本文的源码工程:Netty 粘包/半包原理与拆包实战 源码 本实例是 ...

  2. SpringMVC学习(5):数据绑定2 @PathVariable、@CookieValue、@RequestHeader、@ModelAttribute..

    在系列(4)中我们介绍了如何用@RequestParam来绑定数据,下面我们来看一下其它几个数据绑定注解的使用方法. 1.@PathVariable 用来绑定URL模板变量值,这个我们已经在系列(3) ...

  3. sub

    Popen.communicate(input=None)¶Interact with process: Send data to stdin. Read data from stdout and s ...

  4. 初始 vue

    1.js,jQuery编程范式:命令式编程 vue编程范式:声明式编程 v-for   遍历数组内容 v-on: click   监听点击事件,语法糖 @click el: 类型:string | H ...

  5. 最新版的node安装和配置注意事项

    node在安装的时候,如果你不想用默认的安装路径,可以自定义路径进行安装,例如我的安装路径如下:F:\Program Files\nodejs 安装完成后,要对node进行配置: 在F:\Progra ...

  6. Educational Codeforces Round 65 E,F

    E. Range Deleting 题意:给出一个序列,定义一个操作f(x,y)为删除序列中所有在[x,y]区间内的数.问能使剩下的数单调不减的操作f(x,y)的方案数是多少. 解法:不会做,思维跟不 ...

  7. Codeforces 354B 博弈, DP,记忆化搜索

    题意:现在有一个字符矩阵,从左上角出发,每个人交替选择一个字符.如果最后字符a数目大于字符b,那么第一个人获胜,否则b获胜,否则平均.现在双方都不放水,问最后结果是什么? 思路:这题需要注意,选择的字 ...

  8. MySQL日志文件与分析

    1.查询日志.慢查询日志.二进制日志对比 查询日志 general_log 会记录用户的所有操作,其中包含增删查改等 可以指定输出为表 慢查询日志 slow_log 只要超过定义时间的所有操作语句都记 ...

  9. 用私有构造器或者枚举类型强化SingleTon(单例)属性

    单例(singleton)就是一个只实例化一次的类.使类成为单例可能会使它的测试变得困难,因为除非它实现了作为其类型的接口,否则不可能用模拟实现来代替这个单例.下面是几种实现单例的方法: 1.共有静态 ...

  10. 使用conda部署jupyterhub以及ladp验证的安装

    前提:机器安装有conda环境 官方文档:http://jupyterhub.readthedocs.io/en/stable/quickstart.html 1.安装conda3 jupyterhu ...