读书笔记

第九章 伪代码编程过程 The Pseudocode Programming Process
9.1 创建类和子程序的步骤概述 Summary steps of Building Classes and Routines
图9.1 at p216:
创建一个类的步骤 Steps in Creating a class
创建类的总体设计 具体参考第六章 可以工作类
定义类的职责
定义类要隐藏的”秘密”
定义类的接口所代表的抽象概念
决定这个类是否要从其他类派生出来
决定这个类是否可以被派生,即是否能被继承
指出类的关键公用方法
标识并设计出类所需要的重要数据成员
创建类的子程序 Steps in Building a routine
图9.2 at p217
子程序的种类:成员访问子程序 (accessor routine ),转发到其他对象(pass-throughs)的子程序
步骤:设计子程序->检查设计->编写子程序的代码->检查代码
复审并测试整个类 :在子程序创建的同时经过测试,在整个类可以工作后,应该再对整体进行复查和测试,以便于发现在子程序独立测试层次上无法发现的问题
9.2 伪代码 Pseudocode for Pros
伪代码:描述 算法、子程序、类或者完整程序的工作逻辑、非正式的、类似英语的记法
伪代码的注意事项:
用类似英语的语句来精确描述特定的操作
避免使用目标编程语言的元素,伪代码是比代码本身略高的设计层次,使用目标编程语言的元素会降低设计层次
在本意 intent 层面编写伪代码
在足够低的层次编写伪代码,以便可以近乎转化为代码
好的伪代码能转换为注释
伪代码的好处:
伪代码使得评审更容易
伪代码支持反复迭代精化思想:自顶向下,逐层拆解问题,解决问题
伪代码使变更更加容易
伪代码能使给代码作注释的工作量减少
伪代码比其他设计形式的文档更容易维护
9.3 通过伪代码编码过程创建子程序
设计子程序 Design the Routine
检查先决条件:子程序工作是否定义好,是不是与整体设计相匹配。是否项目必需的
定义子程序的解决的问题:
子程序要隐藏的信息
子程序的输入
子程序的输出
调用子程序前确保有关的前条件成立(输入数据在特定范围内,流已经初始化等)
在子程序将控制权交回调用程序前,确保后条件成立(输出数据在特定范围内,流已经关闭)
为子程序命名
决定如何测试子程序
在标准库搜索可用的功能:重用好的代码,不重复造轮子
考虑错误处理
考虑效率问题:
第一种情况绝大数系统而言,效率并不是十分紧要。另一种情况是对少数系统而言性能非常重要。在除了上述两种情况,在子程序效率的优化是白费功夫的,因为主要的优化是在于完善高层的设计
研究算法和数据类型
编写伪代码:先写头注释 head comment,再写伪代码
考虑数据
检查伪代码:确认很容易,很自然地理解子程序做些什么以及怎样做
在伪代码中试验一些想法,留下最好的想法(迭代):伪代码试验想法成本比代码低。
用伪代码反复描述这个子程序,直到伪代码写出句子已经足够简单,你可以把伪代码直接变成代码文档为止。最初伪代码层次太高,不断的精化和分解伪代码,直到再写伪代码实在浪费时间为止
编写子程序代码 Code the Routine
图9.3 at p225
写出子程序的声明:把如果接口名称起得直接了当,就不需要接口假定(interface assumption)的事情
把伪代码转变为高层次的注释
在每条注释下填充代码: 伪代码相当于文章的提纲,每段伪代码注释描述类一段或者一句代码
检查代码是否需要进一步分解
如果一行伪代码下的代码过多,可以refactor重构成一个子程序
递归recursively地应用伪代码编程过程。如果一行伪代码下的代码过
多,可以把一行伪代码拆分为多行伪代码
检查代码 Check the Code
在脑海检查程序的错误:当子程序足够短小精悍,检查到程序所有可能的执行路径、端点和异常情况,不但要自己查(这叫桌面检查 desk checking),可以同行审查peer review,详查walk-through或者审查inspection
从superstition***迷信到理解*,调查显示只有5%的错误是由于编译器或者硬件造成的,所以遇到的错误大部分都是程序员自身造成的
编译子程序:把编译器的警告级别调到最高,使用像lint的检查工具,及时消除产生错误信息和警告的所有根源
在调试器中逐行运行代码
测试代码
消除程序中的错误
收尾工作 Clean Up LeftOvers
检查子程序的接口
检查子整体的设计质量:内聚性;子程序间松散耦合;防御式编程C7
检查子程序的变量C10-13
检查子程序的语句和逻辑:有无泄漏资源,错误,死循环,错误嵌套C14-19
检查子程序的布局:格式化 C31
检查子程序的文档
除去冗余的注释
9.4 伪代码编程过程的替代方案 Alternative to the PPP
测试先行开发(测试驱动开发)Test-first Development:在任何代码之前先要写出测试用例,使得程序可测试
重构refactoring C24
契约式设计 design by contract 即每一段程序都具有前条件preconditions和后条件postconditions
东拼西凑hacking
核对表 P233
第三部分 变量 Variable
第十章 使用变量的一般事项 General Issue in Using Variables
10.1 数据认知: 列举的常见的数据类型
10.2 轻松掌握变量定义:
隐式声明:避免隐式声明,可能导致编译器的初始值不符合编程的要求,应该关闭隐式声明,并声明全部变量;
10.3 变量初始化原则:
初始化错误:
从未对变量赋值
变量值已经过期
变量的一部分被赋值
避免初始化方法:
在声明时初始化变量
在靠近变量第一次使用的地方初始化它
*理想状态下*,在第一次使用的地方声明并初始化变量
在可能的情况下,使用final或者const
在计数累加器i j,再次使用时忘记重置是一个常见的错误
在类的构造函数中初始化该类数据成员
检查变量是否需要重新初始化
一次性初始化具名常量,用可执行代码初始化变量。
10.4 作用域 Scope
使变量引用局部化:跨度span:变量引用点之间的距离;应该把变量的引用点集中起来
、 * 尽可能缩短存活时间:就是变量最初引用点到最后引用点之间的距离
减少作用域的一般原则:
在循环开始前初始化该循环里使用的变量,而不是在该循环所属的子程序开始处初始化这些变量
直到变量即将被使用的时候再为其赋值
把相关的语句放在一起
把相关的语句提出成单独的子程序
开始时采用严格的作用域,然后根据需要扩展变量的作用域
private -> protected -> default- >public

10.5 持续性:有可能数据发生了变化,引用了过期的变量导致错误
在子程序加入调试代码或者断言检查关键数据的合理性
准备抛弃变量时给它设置不合理的值 个人认为在at C++
编写程序假定是没有持续性的,但不适合c++或者java中的static数据
养成使用所有数据前声明和初始化的习惯
10.6 绑定时间:绑定时间越早灵活性越差,其实跟上面的初始化变量的指导是一样的
10.7 数据类型和控制结构之间的关系:
序列型数据翻译为程序中的顺序语句
选择型数据翻译为程序中的if else语句
迭代型数据翻译为for repeat while等循环语句
10.8 为变量指定单一用途
每个变量只用于单一的用途
第十一章 变量名的力量
11.1 选择好变量名的注意事项
最终重要的命名事项:
名字要完全、准确地表达该事物
容易阅读、不包含晦涩的缩写、同时无歧义
以问题为导向:好的名字是表达”什么“(what)而不是”如何“(how),即反映问题而不是解决方案。变量应直指问题的领域而非计算机世界
inputRecord 比 employeeData
最适当的名字长度 Optimum Name Length:
有研究是平均长度在10到16个字符
有研究是平均长度在8到20个字符
最重要是强调当自己代码中出现很多更短的名字,认真检查确保名字含义足够清晰
变量名对作用域的影响 The Effect of Scope on Variable Names、
对位于全局命名空间中的名字加入限定词
如果编程语言不支持命名空间,就在对应的子系统加入前缀
变量名中计算值限定空间 Computed-Value Qualifiers In Variable Names
把总额 sum total、平均数 average 、最大值Max、最小值Min、记录Record、字符串String、Pointer指针加入名字的后面
revenueTotal revenueAverage更具对称性,更容易维护
Num放在开始位置代表总数,放在结束位置代表一个下标
customerCount代表员工总数 customerIndex代表某个特定的员工
变量名中的对仗词 Common Opposites In Variable Names
* begin/end
first/last
locked/unlocked
min/max
next/previous
old/new
opened/closed
visible/invisible
source/target
source/destination
up/down
11.2 为特定类型的数据命名 Naming Specific Types of Data
为循环下标命名 Naming Loop Index:
一般情况下使用i、j、k
多层循环嵌套的情况或者循环长度超过一两行代码,应该给计数器赋予更长的名字以表达其含义
为状态变量命名 Naming Status Variables
为状态变量取一个比flag更好的名字
标记应该用枚举类型、具名常量或者作为具名常量的全局变量对其进行赋值,增加可读性
为临时变量命名 Naming Temporary Variables:在使用temp等命名前最好思考是否有能表达其含义的名字
为布尔变量命名 Naming Boolean Variables:
谨记典型的布尔变量命名:
done 表示事情是否完成,未完成前是false,完成后是true
error 表示有错误发生,错误发生前是false,错误发生后是true
found 表示某个值已经找到,在未找到该值前是false,找到该值后是true
success或者ok 表示一项操作是否成功,失败是false,成功是true
为布尔变量赋予隐含“真/假”含义的名字
status不是一个好的命名
isXXX优点是:不能用于哪些模糊的名字。缺点是可读性较差
isStatus无意义 isFound 比found可读性差
使用肯定布尔命名
为枚举变量命名 Naming Enumerated Types:
可以通过使用组前缀为明确表示该类型的成员都同属于一个组
Color_XXX
对于枚举的命名有不同的观点:有大小写混合Color_Blue;与常量类似的大写Color.BULE
在处理枚举像类的编程语言里,处理枚举很像类,所以枚举成员总是冠以枚举名字前缀,就无需重复前缀了
为常量命名 Naming Constans:应命名该常量代表的抽象事物而非数值
11.3 命名规则的力量 The Power of Naming Covenstions
为什么要有规则
要求你更多按规矩办事,集中精力投入关注代码更重要的特征
有助于项目之间传递知识
有助于学习新项目
有助于减少名字增生 name Proliferation
弥补编程语言的不足
强调相关变量之间的关系:把相关变量设置相同前缀将它们关联起来
何时采用命名规则
多人开发
程序需要转交别人
程序规模太大,无法同时了解全局,必需分而治之
程序开发周期过长
一个项目存在一些不常见的术语,在编写代码中使用术语或者缩写的时候
11.4 非正式命名规则 Informal Naming Conventions
与语言无关的命名规则指导原则
与语言相关的命名规则指导原则:有C,C++,只列举Java
i,j是整数下标
常量全部大写并用下划线分割
类名和接口每个单词首字母大写
变量名和方法名第一个单词首字母小写,后续单词首字母大写
除用于全部大写的名字外,不使用下划线作为名字中的分隔符
访问器子程序使用get和set前缀
混合语言编程注意事项
命名规则示例
包含以下三类信息:
变量的内容(是什么)
数据的种类(具名常量,简单变量,用户自定义类型或者类)
变量的作用域(局部,私用的,类的,包的或者全部的作用域)
类成员数据:mXXX,全局变量:gXXX
11.5 标准前缀 Standardized Prefixes:分用户自定义类型(UDT)的缩写和语义前缀
用户类型缩写 User-Defined Type Abbreviation:UDT缩写可以标识被命名对象或者变量的数据类型
语义前缀 Semantic Prefixes:描述变量或者对象是如何被使用的
c:count 数量
first:数组需要处理的第一个元素
g:全局变量
i:数组的下标
last:数组中需要处理的最后一个元素
lim:数组中需要处理的元素上限,是非法的,不存在的上限,而last是合法的
m:类一级的变量
min:数组或者其他种类列表中绝对最前一个元素
max:数组或者其他种类列表中绝对最后一个元素
p:pointer 指针
标准前缀的优点:使名字更紧凑、增加可读性
11.6 创建具备可读性的短名字 Creating Short Names That Are Readable
缩写的一般指导原则:
使用标准缩写(参考词典)
去掉所有非前置元音???
computer->cmptr screen->scrn
去掉虚词
and、or、the等
使用每个单词的第一个或者前几个字母
统一地使用单词的第一、第二或者第三(自行确定)字母后截断
保留每个单词的第一和最后一个字母
使用名字中每个重要单词,最多不超过3个
去除无用的后缀
ed,ing
确保不要改变变量的含义
11.7 应该避免的名字 Kind of Names To Avoid
避免使用令人误解的名字或者缩写
避免使用具有相似含义的名字
避免使用具有不同含义但是相似名字的变量:
一般是缩写很相似的情况如 clientReq 和 clientRes
避免使用发音相似的名字
避免在名字中使用数字
避免拼错单词
避免使用容易拼错的单词
不要仅靠大小写来区分变量名
避免使用多种自然语言:只有英语,不使用汉语等
避免使用标准类型、变量和子程序名字:编程语言的关键词
不要使用与变量含义无关的名字
避免在名字中使用容易混淆的字符:数字1对于字母l或者字母i,数字2对应字母z,数字5对应字母s,数字6对应字母g,数字0对应字母o

posted @ 2021-12-01 10:54  大风吹爱护  阅读(45)  评论(0编辑  收藏  举报