代码大全

代码大全

意义

  1. 系统性复习软件开发的知识
  2. 作为会赋能,随时可以打鸡血,懂目标管理,懂时间管理,道术器用齐活,当然能通过科学手段搞定它。
  3. 老哥这本书写得这么厚,恐怕是在刁难我,我必须证明难不倒我。
  4. 我是一名终身成长者,不可能被这本破书吓到,也就是一个小障碍而已。
  5. 1000页的专业书都看完了,以后没有看不下的书。
  6. 优化自己的阅读流程。
  7. 读完可以出去装个x。

标准,结硬寨,打呆仗

  1. 笔记标准,每章必须摘录所有标题结构、摘要和所有加粗字,有代码示例的自己写or摘抄一段,记录所有检查清单
  2. 阅读标准,顺序阅读,每天阅读量不超过两章。
  3. 时间标准,用番茄钟,每次阅读25分钟停下休息。

笔记结构

# 第
## 结构
## 其他章节关联
# 思考&收获
# 笔记

概览

第一部分,1-4章,软件开发中的前期准备。
第二部分,5-9章,如何编写高质量的代码。
第三部分,10-13章,变量
第四部分,14-19章, 语句
第五部分,20-26章,代码改善
第六部分,27-30章,系统考虑
第七部分,31-35章,软件工艺

第1章 软件构建

整体流程:

  1. 定义问题
  2. 需求分析
  3. 规划构建
  4. 软件架构
  5. 详细设计
  6. 编码调试
  7. 单元测试
  8. 集成测试
  9. 集成
  10. 系统测试
  11. 保障维护‘

软件构建部分:

  1. 详细设计
  2. 编码调试
  3. 单元测试
  4. 集成测试
  5. 集成
  6. 系统测试

第2章 隐喻、范型

我得吐槽下第2章软件隐喻。
一开始看摘要,作者亮出了Why,How,What,我还以为他要用黄金思维圈给我们分析下怎么把隐喻用的软件开发中。
在Why这一段,作者用了五六个例子来说明隐喻为什么这么重要,引起了我的好奇。
看到How时,他谈的是怎么用(how to use)而不是怎么做(how to do),更像Where,用在哪里,我就感觉这递进关系有点不对。
到后面What时,原来他是在用隐喻给我们解释,软件开发流程是像写作呢,还是像种田呢,还是像养牡蛎呢,还是像盖房呢。
原来是我想太多,老哥你前面的铺垫这么长,结果给我们看这个,让我有点失望啊。

Why:为什么要用隐喻

  1. 将不太理解的东西和容易理解且类似的东西比较,以提高理解。

像:病毒、bug、木马...

Where:用在哪

  1. 对编程问题进行理解和洞察
  2. 思考编程过程中的活动

What:有些什么类比

  1. 对比写作:写作更多是原创,而软件讲究复用。
  2. 对比种田:软件开发并不是春种一粒粟,秋收万颗籽。
  3. 对比牡蛎:软件增量式开发类似牡蛎的自生长。
  4. 对比盖房:软件开发中类似架构,脚手架,构建等概念都是化用的建筑学中的概念,它们之间有很多类似的思想。

更多

《科学革命的结构》。中译本推荐台湾的程树德的翻译版本,内地的版本翻译太烂。
http://ishare.iask.sina.com.cn/f/21178114.html
Floyd,Robert W.The paradigms of Programming,1978图灵奖颁奖演讲。
《Communications of the ACM》,August 1979,pp.455-460

第3章 前期准备

3.1 Why

  1. 保证全程强调质量

论据

  1. 逻辑:先计划
  2. 类比:盖房先有蓝图
  3. 数据:根据统计,问题发现得越晚,代价越大。

3.2 软件类型

  1. 商业系统
  2. 使命攸关的系统
  3. 性命攸关的系统

瀑布开发与迭代开发

3.3 问题定义

  1. 解决什么
  2. 范畴界定

3.4 需求

  1. 做什么

检查清单,见检查清单目录

3.5 架构

组成:

  1. 程序组织结构
  2. 主要的类
  3. 数据设计
  4. 业务规则
  5. 用户界面设计
  6. 资源管理:软硬件环境
  7. 安全性
  8. 性能
  9. 可伸缩性:弹性扩展
  10. 互用性:与其他系统共享的资源
  11. 国际化/本地化
  12. 输入输出
  13. 错误处理
  14. 容错性
  15. 可行性
  16. 冗余:健壮性
  17. 决策:买or造
  18. 服用
  19. 应对变更

检查清单,见检查清单目录

3.6 时间开销

问题定义+需求分析+架构:10-20的工作量,20-30的时间(%)

扩展的书籍

中译本《软件需求第2版》,清华大学出版社
中译本《掌握需求过程》,人民邮电出版社
中译本《软件需求》,电子工业出版社。
中译本《实用软件需求》,机械工业出版社
:影印版《编写有效用例(英文版)》中译本《编写有效用例》,机械工业出版社。
影印版《软件构架实践(影印版第2版)》,中译本《软件构架实践》,清华大学出版社。中译本《面向模式的软件体系结构卷1:模式系统》,机械工业出版社。
影印版《软件构架编档(影印版)》,中译本《软件构架编档》,清华大学出版社。
影印版《软件构架评估(英文影印版),中译本《软件构架评估》,清华大学出版社
影印版《企业应用架构模式(影印版)》,中国电力出版社;中译本《企业应用架构模式》,机械工业出版社。
影印版《统一软件开发过程(英文影印版)》,清华大学出版社;中译本《统一软件开发过程》机械工业出版社

第4章 关键构建的决策

4.1 语言选择

本书没有淡到如何选择语言,可参考本站dev.chukai.pro,《评估技术or编程语言》一文

4.2 编程风格

本书没展开,需扩展

4.3技术浪潮中的位置

意思是看清技术趋势,投入到那一个时期,早期,中期,晚期。

第5章 软件构建中的设计

结构

  1. 5.1、设计中的挑战
  2. 5.2、关键的设计概念
  3. 5.3、设计构造块:启发式方法
  4. 5.4、设计实践
  5. 5.5、对流行的设计方法的评论

其他章节关联

  1. 软件架构:3.5节
  2. 可以工作的类:6章
  3. 高质量的子程序:7章
  4. 防御式编程:8章
  5. 重构:24章
  6. 程序规模对构建的影响:27章

笔记

高内聚,低耦合。

5.1、设计中的挑战

  1. 设计是个险恶的问题:只有开发上线之后才能知道设计得对不对。
  2. 设计过程是了无章法的:难以判断何时是足够好了。
  3. 设计是取舍和不断调整的过程。
  4. 设计受到很多限制:资源、时间、空间。
  5. 设计是不确定的:同样的需求可以有多个方案。
  6. 设计是启发式过程:很多时候都是探索试试。
  7. 设计是自然形成的:经过不断的迭代。

5.2、关键的设计概念

管理复杂度

开发中的两大难题:本质问题(一般性问题)和偶然问题(异常bug),根源:复杂度。
Why:
降低难度,减少思考负担。
How:
原因:用复杂方法解决简单问题;用简单但错误的方法解决复杂问题;用不恰当的复杂方法解决复杂问题。
手段:
降低本质问题的复杂度,如通过自动化,IDE工具处理。
防止偶然问题复杂度增长。

理想设计特征

  1. 最小复杂度
  2. 易于维护
  3. 松散耦合
  4. 可扩展性
  5. 可重用性
  6. 高扇入:大量类使用某个给定类,有效复用低层次的工具类。
  7. 低扇出:一个类适中的使用其他类,减少字段(最好不超过7个)
  8. 精简性
  9. 层次性
  10. 使用标准技术

设计的层次

  • L1,软件系统
  • L2,子系统和包
    • 常见子系统:业务规则,如薪资系统的税率规则;用户界面;数据库访问;硬件驱动系统。
  • L3,分解的类
  • L4,分解的子程序:一般是函数
  • L5,子程序内部设计

5.3、设计构造块:启发式方法

找出现实中的对象

  1. 辨别对象和属性
  2. 确定对象操作
  3. 确定对象对其他对象的操作
  4. 确定哪些部分对其他对象可见
  5. 定义对象的接口

形成一致的抽象

封装实现细节

继承能简化时则继承

信息隐藏

  1. 尽量不暴露类内部工作机制

两类:隐藏复杂度,隐藏变化源

  • 障碍
    • 信息分散:到处都是相同的魔数
    • 循环依赖
    • 把内部数据误当作全局数据
    • 过早优化:认为额外的信息隐藏会带来性能问题

找出容易改变的区域

  1. 找出看起来容易变化的区域
  2. 把容易变化的项目分离
  3. 把容易变化的项目隔离

    区域:

  4. 业务规则
  5. 硬件依赖
  6. 输入输出
  7. 非标准语言特性
  8. 困难的设计区域和构建区域
  9. 状态变量:枚举代替布尔;函数代替直接判断
  10. 数据量的限制:隐藏常量

预料不同程度的变化

保持松耦合

  • 耦合标准
    • 规模
    • 可见性
    • 灵活性:容易改动
  • 耦合种类
    • 简单数据类型参数耦合,正常
    • 简单对象耦合:模块实例化对象,不错
    • 对象参数耦合:对象当参数,紧密
    • 语义耦合:这类最危险,模块需要知道其他模块的语义,也就是内部逻辑。

查阅常用的设计模式

好处:

  1. 现成的抽象减少复杂度
  2. 制度化减少出错
  3. 更容易想到的设计方案,有启发性价值
  4. 通过概念简化交流成本

其他启发式方法

  1. 高内聚性
  2. 构造分层结构
  3. 严格描述类契约:行为一致
  4. 思考对象分配哪些职责
  5. 为便于测试而设计
  6. 避免失误:考虑失败场景
  7. 绑定时间:什么时候绑定变量,早期,运行期
  8. 创建中央控制点:每一段代码只有唯一的地方可以看到
  9. 可以考虑蛮力突破
  10. 画图
  11. 保持设计的模块化

5.4、设计实践

分治

自上而下和自下而上

视情况而定

建立试验性原型

demo

合作设计

找同事

多少设计才够

越复杂,越长,设计越细

记录设计成果

  1. 设计文档
  2. wiki
  3. 总结邮件
  4. 拍照
  5. 保留设计挂图
  6. 卡片
  7. UML图

5.5、对流行的设计方法的评论

提供了一些书籍参考

  • 软件设计一般性问题
    • The Object-oriented thought process
    • object-oriented design heuristics
    • esssays on software design
    • object-oriented software construction
    • the art of unix programming
    • applying uml and patterns:an introduction to objext-oriented analysis and design and the unified process
  • 设计理论
    • A rational design process: how and why to fake it
    • on the criteria to ne used in decomposing systems into modules
    • designing software for ease of extension and contraction
    • the modular structure of complex systems
  • 设计模式
    • Design patterns
    • design patterns explained
  • 广义设计
    • conceptual blockbusting:a guide to better ideas
    • how to solve it : a new aspect of athematical method
    • how to solve it : modern heuristics
    • the sciences of the artificial
    • software creativity
    • design paradigms:case histories of error and judgment in engineering

第6章 可以工作的类

结构

  1. 6.1 类的基础:抽象数据类型
  2. 6.2 良好的类接口
  3. 6.3 有关设计和实现的问题
  4. 6.4 创建类的原因
  5. 6.5 与具体编程语言相关的问题
  6. 6.6 超越类:包

其他章节关联

  1. 软件构建中的设计:5章
  2. 软件架构:3.5节
  3. 高质量的子程序:7章
  4. 伪代码编程过程:9章
  5. 重构:24章

思考&收获

ADT部分收获很大,可以参照修正代码风格。

笔记

6.1 抽象数据类 ADT(Abstarct data type)

例子

用a.setSize()代替 a.size=10,即以方法初始化代替赋值初始化。

好处

  1. 隐藏实现,无需改动多处。
  2. 影响更小
  3. 程序自说明,方法即注释
  4. 提高性能
  5. 更容易读懂
  6. 无需到处传递数据
  7. 操作对象,而不是操作代码行

6.2 良好的类接口

好的抽象

  1. 抽象层次,分类合理,业务代码和控制代码分离
  2. 理解类对应的抽象是什么
  3. 提供成对的服务,比如启动和停止
  4. 把无关信息转移到其他类
  5. 让接口可编程,而不是表达语义:不假定接口会被如何使用
  6. 在修改时谨防破坏抽象
  7. 不添加不一致的公用属性成员
  8. 同时考虑抽象和内聚

良好的封装,黑盒

  1. 限制可访问性
  2. 不公开暴露成员数据
  3. 不假设用户使用前提
  4. 不使用友元
  5. 阅读优于编码
  6. 不透过语义编程:联系作者优化接口文档,而不是看源码,以方便后来的人。

6.3 设计和实现

  • 组合:has a 关系
    • 尽可能不用继承实现
    • 不超过7个数据成员
  • 继承:is a 关系
    • public 继承
    • 继承进行详细说明,否则不用
    • Liskov替换:派生类能通过基类接口使用,而不需要了解两者的差异
    • 确保只继承需要继承的部分
    • 不要覆盖私有方法
    • 把共用尽可能放到继承树的顶端
    • 只有一个实例的类值得怀疑:单例例外
    • 只有一个派生类的基类也值得怀疑
    • 派生后覆盖了某个子程序,但没有做任何操作,值得怀疑
    • 避免继承体系过深
    • 统筹考虑多态和switch
    • 数据字段private
  • 函数与数据成员
    • 子程序尽可能的少
    • 禁止隐式产生不需要的函数:如不需要默认构造函数(单例下)
    • 减少类调用的不同子程序数量
    • 对其他类的子程序调用尽可能的少
    • 减少类与类的合作范围
      • 实例化的对象种类
      • 不同子程序的数量
  • 构造函数
    • 如果可以,初始化所有成员
    • 单例私有化构造
    • 优先使用深copy

6.4 创建类的原因

  1. 为现实对象建模
  2. 为抽象的对象建模
  3. 降低复杂度
  4. 隔离复杂度
  5. 隐藏实现细节
  6. 限制变动的影响范围
  7. 隐藏全局数据
  8. 让参数传递更舒畅
  9. 建立中心控制点
  10. 让代码易于重用
  11. 为程序族做计划
  12. 把相关操作包装在一起
  13. 实现某种特定的重构

    应该避免的类:

  14. 万能类
  15. 无关紧要的类
  16. 动词命名类:需要与数据绑定

6.5 与具体编程语言相关的问题

Java等语言特性

6.6 超越类:包

按层次或聚类制定包

第7章 高质量的子程序

结构

7.1 创建子程序的正当理由
7.2 在子程序层上设计
7.3 好的子程序名字
7.4 子程序可以写多长
7.5 如何使用子程序参数
7.6 使用函数时特别考虑的问题
7.7 宏子程序和内联子程序

其他章节关联

构造子程序的步骤 9.3节
可以工作的类 6章
一般设计技术 5章
软件架构 3.5节

思考&收获

子程序=函数+过程
过程:语义上为无返回值的函数
抽象的本质:封装细节
例:

while(node.name==name){
    node=node.next;
}
return node;
--- 
同抽象更好的代码
node=getNodeByName(name)

笔记

7.1 创建子程序的正当理由

  1. 降低复杂度
  2. 引入更好的抽象
  3. 避免代码重复
  4. 支持子类化:重写(override)时代码更少
  5. 隐藏循序:对用户隐藏执行顺序
  6. 隐藏指针操作
  7. 提高可移稙性
  8. 简化复杂的布尔判断
  9. 改善性能:只需优化一处

简单计算也可以写成子程序,阅读更好。

7.2 在子程序层上设计

  • 内聚性
    • 功能内聚性:一个子程序只做一个操作
    • 顺序内聚性:顺序执行多个操作,可以优化成多个。
    • 通信内聚性:在一个中不同操作使用同样数据,可以拆分
    • 临时内聚性:例如start(),shutdown()放一起
  • 不可取的内聚性:
    • 过程内聚:只是在同一流程上,无共性
    • 无逻辑内聚
    • 巧合内聚

7.3 好的子程序名字

  1. 描述子程序所做的所有事
  2. 避免无意义的动词
  3. 不要用数字形成不同的名字
  4. 最佳长度9-15
  5. 对返回值的有所描述
  6. 动词+宾语
  7. 准确使用对仗词
  8. 为常用操作确立命名规则

7.4 子程序可以写多长

推荐<200行

7.5 如何使用子程序参数

  1. 按输入、修改、输出的顺序排列
  2. 定义IN OUT (C++)
  3. 不同子程序参数类似时,顺序也保持一致
  4. 不传不使用的参数
  5. 把状态量和错误码放最后
  6. 不要把入参当成操作变量
  7. 在编码子程序前注释对入参的假定
  8. 参数最好<7
  9. 考虑对输入、输出、修改的参数使用前缀,如out_,in_,motify_
  10. 为子程序传递对象的个别变量还是整个对象:取决的具体的抽象逻辑。
  11. 使用具名参数
  12. 确保实参与形参匹配

7.6 使用函数时特别考虑的问题

何时使用函数,何时使用过程

返回有其名字指明的返回值用函数,否则过程

设置函数的返回值

  1. 检查所有可能的返回路径:现在基本由ide处理了
  2. 不要返回所有指向局部数据的引用或指针

7.7 宏子程序和内联子程序

  1. 宏表达式放在括号中
  2. 给代码形同子程序的宏用子程序的风格命名,便于重构
  3. 限制
    • 不到万不得以,不使用宏

第8章 防御式编程

结构

8.1 保护程序免遭非法输入数据的破坏
8.2 断言
8.3 错误处理技术
8.4 异常
8.5 隔离程序,使之包容由错误造成的损害
8.6 辅助调试的代码
8.7 确定在产品代码中该保留多少防御式代码
8.8 对防御式编程采取防御的姿态

其他章节关联

信息隐藏 5.3节
为变更而设计 5.3节
软件架构 3.5节
软件构建中的设计:5章
调试 23章

思考&收获

笔记

8.1 保护程序免遭非法输入数据的破坏

  1. 检查所有源于外部的数据
  2. 检查子程序输入参数
  3. 决定如何处理错误数据

8.2 断言

开发时使用

建议

  1. 用断言来处理绝对不可能发生的状态
  2. 避免把需要执行的代码放到断言中
  3. 用断言来验证前条件和后条件
  4. 高健壮性代码先断言再处理错误

8.3 错误处理技术

  1. 使用中立值
  2. 换用下一个正确数据
  3. 返回前一次相同数据
  4. 用最接近合法的值
  5. 打出日志
  6. 返回错误码
  7. 调用错误处理子程序
  8. 提示给用户
  9. 用合适的方式在局部处理
  10. 关闭程序

正确与健壮性:与生命相关的优先正确

高层次设计统一错误处理

8.4 异常

  1. 用异常通知其他程序,发生了不可忽略的错误
  2. 只在真正例外的情况下抛出异常
  3. 不能用异常来推卸责任
  4. 避免在构造和析构函数中抛出异常
  5. 在恰当的抽象层抛出
  6. 在异常消息中加入全部错误信息
  7. 避免使用空的catch语句
  8. 了解所用函数库的异常
  9. 考虑创建一个集中的异常报告机制
  10. 把项目中对异常的使用标准化
  11. 考虑异常的代替方案

8.5 隔离程序,使之包容由错误造成的损害

  1. 把输入数据转化的恰当类型

8.6 辅助调试的代码

  1. 不要把对产品的限制加在开发版上,可以为了简化开发使用适当手段
  2. 尽早加入辅助调试代码
  3. 采用进攻式编程:对异常场景使用最高级别的中断
  4. 计划移除调试代码:使用预处理器

8.7 确定在产品代码中该保留多少防御式代码

  1. 保留重要错误的代码
  2. 去掉细微错误的代码
  3. 去掉会导致程序硬性崩溃的代码
  4. 保留会让程序稳妥崩溃的代码
  5. 为技术支持人员记录错误日志
  6. 确认错误消息是友好的

8.8 对防御式编程采取防御的姿态

第9章 伪代码编程过程

结构

9.1 创建类和子程序的步骤描述
9.2 伪代码
9.3 通过伪代码编程过程创建子程序
9.4 伪代码编程过程的替代方案

其他章节关联

创建高质量的类 6章
高质量的子程序 7章
软件构建中的设计 5章
注释风格 32章

思考&收获

这章伪代码的编程方式颠覆了我原有的认知。
也就是把伪代码当成开发的方式,先写伪代码,再在伪代码上编程,而不是以前用伪代码说明某些业务场景。
特别是把重构和TDD例为了另外两种编程方式。

笔记

9.1 创建类和子程序的步骤描述

创建类的步骤

  1. 创建类的总设计
  2. 创建类的子程序
  3. 复审并测试整个类

创建子程序的步骤

基于伪代码

9.2 伪代码

9.3 通过伪代码编程过程创建子程序

设计子程序

  1. 检查先决条件
  2. 定义子程序要解决的问题
  3. 为子程序命名
  4. 决定如何测试子程序
  5. 在标准库中搜寻可用的功能
  6. 考虑错误处理
  7. 考虑效率问题
  8. 研究算法和数据类型
  9. 编写伪代码
  10. 考虑数据
  11. 检查伪代码
  12. 在伪代码中试验想法,留下最好的想法

编写子程序的代码

  1. 写出在程序的声明
  2. 把伪代码转变为高层次注释
  3. 在每条注释下填充代码
  4. 检查代码需要进一步分解

检查代码

  1. 在脑海里检查程序中的错误
  2. 编译子程序
  3. 在调试器中逐行执行代码
  4. 测试代码
  5. 消除程序中的错误
  6. 其他收尾工作

9.4 伪代码编程过程的替代方案

  1. 测试驱动开发
  2. 重构
  3. 契约式设计
  4. 东拼西凑

第10章 使用变量的一般事项

结构

10.1 数据认知
10.2 轻松掌握变量定义
10.3 变量初始化原则
10.4 作用域
10.5 持续性
10.6 绑定时间
10.7 数据类型和控制结构之间的关系
10.8 为变量指定单一用途

其他章节关联

为变量命名 11章
基本数据类型 12章
不常见的数据类型 13章
格式化数据声明 31.5节
注释变量 32.5节

思考&收获

具名常量,是指用const修饰的变量。

笔记

10.1 数据认知

数据认知测试 20

10.2 轻松掌握变量定义

有IDE,基本不会有这个问题。
隐式声明

  1. 关闭隐式声明
  2. 声明全部变量
  3. 遵循同样的命名规则
  4. 检查变量名

10.3 变量初始化原则

  1. 在声明变量时初始化
  2. 在靠近变量第一次使用的位置初始化
  3. 理想:在靠近变量第一次使用的位置声明和初始化
  4. 可能情况下使用final const
  5. 特别注意技术器
  6. 在构造函数里初始化
  7. 检查是否需要重新初始化
  8. 一次初始化具名常量;用可执行的代码初始化变量
  9. 使用编译器自动初始化所有变量
  10. 利用编译器警告信息
  11. 检查输入参数的合法性
  12. 使用内存访问检查工具来检查错误指针
  13. 在程序开始时初始化工作内存

10.4 作用域

使变量引用局部化

尽可能缩短变量存活时间

测量变量的生存时间

减小作用域的一般原则

  1. 在循环开始前再初始化该循环使用的变量
  2. 直到变量即将被使用时才赋值
  3. 把相关语句放一起
  4. 把相关语句组提取成单独的子程序
  5. 采用最严格的可见性

10.5 持续性

10.6 绑定时间

10.7 数据类型和控制结构之间的关系

  1. 序列型数据翻译为程序中的顺序语句
  2. 选择型翻译为if 或 case
  3. 迭代型翻译为ofr while

10.8 为变量指定单一用途

  1. 每个变量只用于单一用途
  2. 避免让代码具有隐含含义
  3. 确保使用了所有变量

第11章 变量名的力量

结构

11.1 选择和变量名的注意事项
11.2 为特定的类型的数据命名
11.3 命名规则的力量
11.4 非正式命名规则
11.5 标准前缀
11.6 创建具备可读性的短名字
11.7 应该避免的名字

其他章节关联

子程序名字 7.3节
类的名字 6.2节
使用变量的一般事项 10章
注释变量 32.5节

思考&收获

  1. 命名最好用描述性词汇,不要用temp、flag这类的词

笔记

11.1 选择和变量名的注意事项

  1. 以问题导向,反映what而不是how
  2. 长度8-20
  3. 对全局命名加限定词
  4. Sum,Avg等计算限定词放最后

11.2 为特定的类型的数据命名

  1. 循环下标一般ijk,嵌套用正常变量名
  2. 状态变量不要用flag
  3. 为临时变量命名
  4. 为布尔变量命名
  5. 为枚举变量命名
  6. 常量大写

11.3 命名规则的力量

  1. 提升阅读效率

11.4 非正式命名规则

语言无关的:

  1. 区分变量和子程序名字
  2. 区分类和对象
  3. 区分全局变量、成员变量、类型声明、具名常量、枚举
  4. 格式化

语言相关的

11.5 标准前缀

  • 用户自定义类型缩写:ch,doc,pa,src,sel,wn
  • 语义前缀:c,first,g,i,last,lim,m,max,min,p

11.6 创建具备可读性的短名字

  1. 不要用每个单词删一个字母的方式来缩写
  2. 缩写要一致
  3. 创建你能读出来的名字
  4. 避免使用容易看错的字符组合
  5. 使用辞典解决命名冲突
  6. 注释缩写对照表
  7. 文档中说明

11.7 应该避免的名字

  1. 避免使用令误解的名字或缩写
  2. 避免使用具有相似含义的名字
  3. 避免使用具有不同含义但名字相似的变量
  4. 避免使用发音相近的名字
  5. 避免使用数字
  6. 拼错
  7. 容易拼错的长单词
  8. 不要靠大小写区分变量
  9. 不要用多种自然语言
  10. 不要使用保留字
  11. 不要用含义无关的
  12. 避免含有容易混淆的字符1L,0O,Z2,S5,G6,I1

第12章 基本数据类型

结构

12.1 数值概论
12.2 整数
12.3 浮点数
12.4 字符和字符串
12.5 布尔变量
12.6 枚举类型
12.7 具名常量
12.8 数组
12.9 创建自己的类型

其他章节关联

数据命名 11章
不常见的数据类型 13章
使用变量的一般事项 10章
格式化数据声明 31.5节
注释变量 32.5节
创建类 6章

思考&收获

笔记

12.1 数值概论

  1. 避免使用魔法数
  2. 可以硬编码0,1
  3. 预防除零
  4. 使类型转换变得明显
  5. 避免混合类型比较
  6. 注意编译器警告

12.2 整数

  1. 检查整数除法
  2. 检查整数溢出
  3. 检查中间结果溢出

12.3 浮点数

  1. 避免数量级相差巨大的数加减运算:32位可能位数不够
  2. 避免等量判断
  3. 处理舍入误差
  4. 检查语音对数据类型的支持

12.4 字符和字符串

  1. 避免off-by-one 错误:偏差一,下标从0开始。
  2. 了解语言对Unicode的支持
  3. 尽早考虑国际化

12.5 布尔变量

  1. 用布尔变量对程序加以文档说明
  2. 增加布尔变量简化复杂判断

12.6 枚举类型

  1. 用枚举提高可读性、可靠性
  2. 简化修改
  3. 作为布尔的替代
  4. 检查非法值

12.7 具名常量

  1. 避免使用魔法数
  2. 用具有适当作用域的变量或类模拟具名常量
  3. 统一使用具名常量

12.8 数组

  1. 确认数组不越界
  2. 考虑用容器代替
  3. 检查边界
  4. 多维数组检查下标
  5. 提下标串话

12.9 创建自己的类型

第13章 不常见的数据类型

结构

13.1 结构体
13.2 指针
13.3 全局数据

其他章节关联

基本数据类型:12章
防御式编程:8章
不常见的控制结构:17章
软件开发中的复杂度”5.2节

思考&收获

笔记

13.1 结构体

  1. 用结构体明确数据关系
  2. 简化对数据的操作
  3. 简化参数列表
  4. 减少维护

13.2 指针

内存中的位置
技巧:

  1. 把指针操作限制在子程序或类里
  2. 在与指针分配相同的作用域中删除指针
  3. 在使用指针前检查它
  4. 先检查指针所引用的变量再使用
  5. 用狗牌字段来检测损毁的内存
  6. 增加明显的冗余
  7. 用额外的指针提高代码清晰度
  8. 简化复杂的指针表达式
  9. 画一个图
  10. 按照正确的顺序删除指针
  11. 分配一片保留内存的最后区域
  12. 粉碎垃圾数据
  13. 在删除或释放指针后设为空
  14. 删除变量前检查非法指针
  15. 跟踪指针分配情况
  16. 编写统一处理指针的子程序
  17. 可能采用非指针技术

C++:

  1. 把指针用于按引用传递的参数,把const用于按值传递的参数
  2. 使用auto_ptr
  3. 灵活运用智能指针

C:

  1. 使用显式指针而不是默认类型
  2. 避免强制类型转化
  3. 遵循参数传递的星号规则
  4. 在内存分配中使用sizeof()确认大小

13.3 全局数据

  • 全局数据的问题

第14章 组织直线型代码

结构

14.1 必须有明确顺序的语句
14.2 顺序无关的语句

其他章节关联

一般控制问题 19章
条件代码 15章
循环代码 16章
变量和对象的作用域 10.4节

思考&收获

逻辑的抽象隔离

笔记

14.1 必须有明确顺序的语句

  1. 设法组织代码,使依赖关系变得明显
  2. 使子程序名能凸显依赖关系
  3. 利用子程序参数明确显示依赖关系
  4. 注释不清晰的依赖关系
  5. 用断言或错误处理代码来检查依赖关系

14.2 顺序无关的语句

  • 使代码易于自上而下阅读
  • 把相关语句组织在一起

第15章 使用条件语句

结构

15.1 if语句
i15.2 case语句

其他章节关联

驯服深层嵌套 19.4节
一般控制问题19章
循环代码 16章
直线型代码 14章
数据类型和控制结构之间的关系 10.7

思考&收获

笔记

15.1 if语句

简单的if-then语句

  1. 首先写正常的代码路径,再写不正常的情况。注:也需要要分支复杂度
  2. 确保对于等量的分支是正确的:>和>=
  3. 把正常情况放在if后面
  4. 让if后面跟一个有意义的语句
  5. 考虑else子句
  6. 测试else子句的正确性
  7. 检查if和else是不是弄反了
  8. 利用布尔函数调用简化复杂的检测
  9. 把最常见的情况放在最前面
  10. 确保所有的情况都考虑到了

Fo. 如果你的语言支持,把if else换成其他结构:case,多态。

15.2 case语句

选择最有效的排序

  1. 字母
  2. 正常情况优先
  3. 执行频率优先

技巧

  1. 简化抽取执行子程序
  2. 不要为使用case刻意造变量
  3. 利用default检测错误
  4. 注意break;
  5. 需要跨case时注释

第16章 控制循环

结构

16.1 选择循环的种类
16.2 循环控制
16.3 轻松创建循环-由内而外
16.4 循环和数组的关系

其他章节关联

驯服深层嵌套
一般控制问题
条件代码
直线型代码
数据类型和控制结构之间的关系

思考&收获

通过标号可以直接跳出多层循环,很少用:

void test(){
    loop:for(...){
                for(...){
                    break loop;
                }
            }
}

笔记

16.1 选择循环的种类

  1. 计数循环
  2. 连续求值
  3. 无限循环
  4. 迭代器循环

16.2 循环控制

  1. 进入循环
    1. 只从一个位置进入循环
    2. 把初始化代码紧放循环前面
    3. 用while(true)表示无限循环
    4. 在适当的情况下多使用for
    5. while更适用时不要用for
  2. 处理好循环体
    1. 用{}包裹代码
    2. 避免空循环
    3. 把自增/减操作放在开始或末尾
    4. 一个循环只做一件事情
  3. 退出循环
    1. 设法确认循环能够终止
    2. 使循环终止条件看起来明显
    3. 不要为了终止循环而胡乱改动for循环下标
    4. 不在循环终止后使用循环下标
    5. 考虑使用安全计数器(设置循环上限)
  4. 提前退出循环
    1. 使用break
    2. 小心那些有很多break的循环
    3. 如果语言支持,使用带标号的break
  5. 使用循环变量
    1. 用整数或枚举表示边界
    2. 在嵌套循环中使用有意义的变量名
    3. 用有意义的名字来避免循环下标串话
    4. 把循环变量的作用域限制在本循环体内
  6. 循环多长?
    1. 尽可能的短
    2. 嵌套限制在3层
    3. 长循环要清晰

16.3 轻松创建循环-由内而外

  1. 先写内部逻辑,再写外层循环

16.4 循环和数组的关系

  1. 并没有直接关系

第17章 不常见的控制结构

结构

17.1 子程序中的多处返回
17.2 递归
17.3 goto
17.4 针对不常见的控制结构的观点

其他章节关联

一般控制问题 19章
直线型代码 14章
条件代码 15章
循环代码 16章
异常处理 8.4节

思考&收获

笔记

17.1 子程序中的多处返回

  1. 如果能增强可读性,那就使用return
  2. 用防卫子句来简化复杂错误处理(早返回或早退出)
  3. 减少子程序的return 数量

17.2 递归

  1. 确认递归能停止
  2. 使用安全计数器
  3. 把递归限制在一个子程序内
  4. 留心栈空间
  5. 不要用递归计算阶乘和斐波纳契数列8

17.3 goto

不玩。

17.4 针对不常见的控制结构的观点

第18章 表驱动法

结构

18.1 表驱动法使用总则
18.2 直接访问表
18.3 索引访问表
18.4 阶梯访问表
18.5 表查询的其他示例

其他章节关联

隐藏信息 5.3节
类的设计 6章
用决策表代替复杂逻辑 19.1节
用查询表代替复杂表达式 26.1节

思考&收获

笔记

18.1 表驱动法使用总则

18.2 直接访问

charType=charTypeTanle[inputChar]
  1. 复制信息从而能够直接使用键值
  2. 转换键值以使其能够直接使用:max(min(66.age),17)
  3. 把键值转换提取成独立的子程序

18.3 索引访问表

18.4 阶梯访问表

  1. 留心端点
  2. 考虑用二分查找取代顺序查找
  3. 考虑用索引访问来取代阶梯技术
  4. 把阶梯表查询操作提取成子程序

18.5 表查询的其他示例

第19章 一般控制问题

结构

19.1 布尔表达式
19.2 复合语句
19.3 空语句
19.4 驯服危险的深层嵌套
19.5 编程基础:结构化编程
19.6 控制结构与复杂度

其他章节关联

直线型代码 14章
条件代码 15章
循环代码 16章
不常见的控制结构 17章
软件开发的复杂度 5.2节

思考&收获

笔记

19.1 布尔表达式

  1. 用True和false
  2. 隐式比较布尔值
  3. 简化复杂表达式
    1. 拆分复杂判断并引入新变量
    2. 把复杂的表达式做成布尔函数
    3. 用决策表代替复杂条件
  4. 编写肯定形式的表达式
  5. 用狄摩根定理简化否定的布尔判断
  6. 用括号
  7. 按数值顺序编写数值表达式
  8. 与0比较
    1. 隐式比较逻辑变量:while(!done)
    2. 把数和0比较
    3. 在C中显示的比较字符和零终止符
    4. 把指针和Null比较
  9. 在C中,常量放左边
  10. 在JAVA中理解==和equals

19.2 复合语句

  1. 括号对

19.3 空语句

  1. 小心使用空语句
  2. 考虑换空循环体

19.4 驯服危险的深层嵌套

  1. 合并if
  2. 用break简化嵌套if
  3. 把嵌套if换成if else
  4. 把if换成case
  5. 把嵌套抽取子程序
  6. 使用多态
  7. 重新设计

19.5 编程基础:结构化编程

任何程序都可以用以下三种结构生成

  1. 顺序
  2. 选择
  3. 迭代

19.6 控制结构与复杂度

通过决策点计算复杂度

第20章 软件质量概述

结构

20.1 软件质量的特性
20.2 改善软件质量的技术
20.3 不同质量保障技术的相对效能
20.4 什么时候进行质量保证工作
20.5 软件质量的普遍原理

其他章节关联

协同构建:21章
开发者测试:22章
调试:23章
软件构建的前期准备: 3、4章
前期准备适用于现代软件项目:3.1节

思考&收获

  1. code review比测试成本更低。
  2. 前期质量保证能有效降低成本。

笔记

20.1 软件质量的特性

外在特性:

  1. 正确性
  2. 可用性:用户学习容易成都
  3. 效率
  4. 可靠性
  5. 完整性:阻止未授权访问和正确访问
  6. 适应性:可迁移
  7. 精确性:输出结果误差
  8. 健壮性:应对无效输入和压力环境

内在特性:

  1. 可维护性
  2. 灵活性
  3. 可移植性
  4. 可重用性
  5. 可读性
  6. 可测试性
  7. 可理解性

20.2 改善软件质量的技术

  1. 软件质量目标
  2. 明确定义质量保证工作
  3. 测试策略
  4. 软件工程指南
  5. 非正式技术复查:review
  6. 正式技术复查
  7. 外部审查

开发过程:

  1. 对变更进行控制的过程
  2. 结果的量化
  3. 制作原型

20.3 不同质量保障技术的相对效能

  • 缺陷检测率
  • 找出缺陷的成本
  • 修复缺陷的成本

20.4 什么时候进行质量保证工作

20.5 软件质量的普遍原理

第21章 协同软件构建

结构

21.1 协同开发实践概要
21.2 结对编程
21.3 正式检查
21.4 其他类型的协同开发实践

其他章节关联

软件质量概述
开发者测试
调试
软件构建的前期准备

思考&收获

笔记

21.1 协同开发实践概要

协同构建是其他质量保证技术的补充
有利于传授公司文化以及编程知识

21.2 结对编程

关键:

  1. 用编码规范来支持结对编程
  2. 不要让结对编程变成旁观
  3. 不要强迫在简单问题上使用
  4. 有规律的进行轮换
  5. 鼓励双方跟上对方的步伐
  6. 确认两个人都能够看到显示器
  7. 不要强迫性格不同的人组队
  8. 避免新手组合
  9. 指定一个组长

21.3 正式检查

  • 角色:

主持人
作者
评论员
记录员
经理

  • 步骤

计划
概述
详查会议
详查报告
返工
跟进
第三个小时会议

21.4 其他类型的协同开发实践

  1. 走查
  2. 代码阅读
  3. 公开演示

第22章开发者测试

结构

22.1 开发者测试在软件中的角色
22.2 开发者测试的推荐方法
22.3 测试技巧锦囊
22.4 典型错误
22.5 测试支持工具
22.6 改善测试过程
22.7 保留测试记录

其他章节关联

软件质量概述:20章
协同构建实践 21章
调试 23章
集成 29章
软件构建的前期准备 3章

思考&收获

测试的质量过于乐观

笔记

22.1 开发者测试在软件中的角色

  1. 开发者测试占项目时间的8-25

22.2 开发者测试的推荐方法

测试先行:TDD
局限:

  1. 开发者倾向于做干净测试:检查是否工作,而不是让代码失效
  2. 开发者测试对覆盖率有过于乐观的估计
  3. 往往会忽略更复杂的测试类型

22.3 测试技巧锦囊

结构化基础测试
数据流测试:
数据状态:1.已定义,2.已使用,3.已销毁,
控制状态:1.已进入,2.已退出
等价类划分
猜测错误
边界值分析
复合边界值

22.4 典型错误

bug分布符合28法则
关于错误:

  1. 大多数错误的影响范围有限
  2. 许多错误发生在构建之外
  3. 大多数构建期错误是编程人员失误
  4. 笔误是常见的问题根源
  5. 错误理解设计
  6. 大多错误容易修正
  7. 总结对错误的经验

测试用例本身的错误:

  1. 检查你的工作
  2. 开发时计划测试用例
  3. 保留你的测试用例
  4. 将单元测试纳入框架

22.5 测试支持工具

为测试各个类构建脚手架:mock
设计随机测试数据生成器
覆盖率监视
数据记录器
符号调试器
系统干扰器
错误数据库

22.6 改善测试过程

有计划的测试
重新测试
自动化测试

22.7 保留测试记录

第23章 调试

结构

23.1 调试概述
23.2 寻找缺陷
23.3 修正缺陷
23.4 调试中的心理因素
23.5 调试工具

其他章节关联

软件质量概述 20章
开发者测试 22章
重构 24章

思考&收获

笔记

23.1 调试概述

  1. 理解程序
  2. 明确错误类型
  3. 从代码阅读者的角度分析代码质量
  4. 审视自己的问题解决方法
  5. 审视自己修正缺陷的方法

调试的魔鬼指南

  1. 凭猜测调试
  2. 不把时间浪费在理解问题上
  3. 用最唾手可得的方式修正错误

23.2 寻找缺陷

科学的方法:

  1. 把错误发生稳定下来
  2. 确定错误原因

小建议:
构建假设时覆盖全面
提炼产生错误的测试用例
在自己的单元测试族中测试代码
利用可用的工具
采用不同的方法重现错误
用更多的数据产生更多的假设
利用否定性测试用例的结果
对可能的假设头脑风暴
例出需要的尝试
缩小嫌疑代码的范围
对出现过缺陷的程序保持警惕
检查最近修改过的代码
扩展嫌疑代码的范围
增量式集成
检查常见缺陷
同其他人讨论
休息一下

蛮力调试

给快速调试设置时间上限
做出一张蛮力调试方法列表

语法错误

  1. 不要过分信任编译器的行号
  2. 不要迷信编译器信息
  3. 不要轻信编译器的第二条信息
  4. 分而治之
  5. 找出没有配对的注视或者行号

23.3 修正缺陷

  1. 先理解问题
  2. 理解程序本身
  3. 验证对错误的分析
  4. 放松一下
  5. 保留原始代码
  6. 治本
  7. 修改代码时一定要有恰当理由
  8. 一次只做一个改动
  9. 检查自己的改动
  10. 增加能暴露问题的单元测试
  11. 搜索类似缺陷

23.4 调试中的心理因素

心理取向导致调试盲目

23.5 调试工具

  1. 源码比较工具
  2. 编译器警告信息
    1. 最高级别
    2. 处理警告
    3. 统一编译设置
  3. 增强语法检查
  4. 执行性能测试

第24章 重构

结构

24.1 软件演化的类型
24.2 重构简介
24.3 特定的重构
24.4 安全的重构
24.5 重构策略

其他章节关联

思考&收获

笔记

24.1 软件演化的类型

演化法:www,ejb

24.2 重构简介

WHY:

  1. 代码重复
  2. 冗长的子程序
  3. 循环过长或嵌套过深
  4. 内聚性太差的类
  5. 类的接口未能提供一致的抽象
  6. 太多参数的参数列表
  7. 类的内部修改往往被局限在某个部分
  8. 变化导致多个类相同的修改
  9. 对继承体系的同样修改
  10. case语句需要做相同的修改
  11. 同时使用的相关数据并未以类的方式进行组织
  12. 成员函数使用其他类的特征比使用自身类的特征还要多
  13. 过多使用基本数据类型
  14. 某个类无所事事
  15. 一系列传递流浪数据的子程序
  16. 中间人对象无事可做
  17. 某个类同其他类的关系过于密切
  18. 子程序命名不恰当
  19. 数据成员被设置为公用
  20. 某个派生类仅使用基类的很少一部分成员函数。
  21. 注释被用于解释难懂的代码
  22. 使用了全局变量
  23. 在子程序调用前使用了设置代码
  24. 程序中的代码似乎是在将来的某个时候才会用到。

24.3 特定的重构

数据级重构

  1. 用具名常量代替神秘数
  2. 使变量的名字更为清晰
  3. 将表达式内联化(用函数代替表达式)
  4. 引入中间变量
  5. 用多个单一用途的变量代替单个多用途变量
  6. 在局部用途中的使用局部变量而不是参数
  7. 将基础数据类型转化为类
  8. 将一组类型码转化为类或枚举
  9. 将一组类型码转换为一个基类及其派生类
  10. 将数组转换为对象
  11. 把集合封装起来
  12. 用数据代替传统记录

语句级重构

  1. 分解布尔表达式
  2. 将复杂布尔表达式转换成命名准确的布尔函数
  3. 合并条件语句不同部分中的重复代码片段
  4. 使用break或return而不是循环控制变量
  5. 在嵌套的if then else 语句中一旦知道答案就返回,而不是去赋一个反馈值
  6. 用多态来代替条件语句
  7. 使用Null对象

子程序级重构

  1. 提取子程序或方法
  2. 将子程序代码内联
  3. 将冗长子程序转换为类
  4. 用简单算法代替复杂算法
  5. 增加参数
  6. 删除参数
  7. 将查询操作从修改操作中独立出来
  8. 合并相似的子程序,用参数区分
  9. 将行为取决于参数的子程序拆分开来
  10. 传递整个对象而非特定成员
  11. 传递特定成员而非对象
  12. 包装向下转型操作

类实现的重构

  1. 将值对象转化为引用对象
  2. 将引用对象转化为值对象
  3. 用数据初始化代替虚函数
  4. 改变成员的位置
  5. 将特殊代码提取为派生类
  6. 将相似代码组合起来放到基类

类接口的重构

  1. 将成员函数放到另一个类中
  2. 将一个类变成两个
  3. 删除类
  4. 去除委托关系
  5. 去掉中间人
  6. 用委托代替继承
  7. 用继承代替委托
  8. 引入外部成员函数
  9. 引入扩展类
  10. 对暴露在外的成员变量进行封装
  11. 对于不能修改的类成员,删除相关的Set()成员函数
  12. 隐藏那些不会在类之外用到的成员函数
  13. 封装不使用的成员函数
  14. 合并那些实现非常类似的基类和派生类

系统级重构

  1. 无法控制的数据创建明确的数据源
  2. 将单向类联系改为双向联系
  3. 将双向的类联系改为单向类联系
  4. 用Factory Method 模式而不是简单地构造函数
  5. 用异常取代错误处理代码,或者做相反方向的变换

24.4 安全的重构

  1. 保存初始代码
  2. 重构步伐小些
  3. 同一时间只做一项重构
  4. 把要做的事情列出来
  5. 设置一个暂存区
  6. 多使用检查点
  7. 利用编译器警告
  8. 重新测试
  9. 增加测试用例
  10. 检查对代码的修改
  11. 根据重构风险级别来调整重构方法

不宜重构的情况

  1. 不要把重构当作先写后改的代名词
  2. 避免用重构代替重写

24.5 重构策略

  1. 增加子程序时
  2. 添加类时
  3. 改bug时
  4. 关注易于出错的模块
  5. 关注高度复杂的模块
  6. 在维护环境下,改善你手中正在处理的代码
  7. 定义清楚干净代码和拙劣代码的便捷

第25章 代码调整策略

结构

25.1 性能概述
25.2 代码调整简介
25.3 蜜糖和哥斯拉
25.4 性能测量
25.5 反复调整
25.6 代码调整方法总结

其他章节关联

代码调整技术 26章
软件架构 3.5节

思考&收获

笔记

25.1 性能概述

方式:

  1. 确认需求
  2. 优化功能设计
  3. 优化类和子程序
  4. 同操作系统的交互
  5. 代码编译
  6. 硬件
  7. 代码调整

25.2 代码调整简介

  1. 28法则

注意:

  1. 运行速度与行数无关
  2. 不要过早优化
  3. 速度与正确的平衡

when:

  1. 完成后再优化

通过编译器优化,比如升级jdk

25.3 蜜糖和哥斯拉

常见的抵效率之源

  1. IO
  2. 系统调用
  3. 解释型语言

25.4 性能测量

25.5 反复调整

25.6 代码调整方法总结

第26章 代码调整技术

结构

26.1 逻辑
26.2 循环
26.3 数据变换
26.4 表达式
26.5 子程序
26.6 用低级语言重写代码
26.7 变得越多,事情反而没变

其他章节关联

代码调整策略 25章
重构 24章

思考&收获

笔记

26.1 逻辑

  1. 短路求值
  2. 按出现的频率调整判断顺序
  3. 用查询表代替复杂表达式
  4. 惰性求值

26.2 循环

  1. 合并
  2. 展开
  3. 减少循环内部的重复工作
  4. 哨兵值
  5. 把最忙的循环放在内层(然而JDK11实际测试下来是反的)
  6. 削减强度(加代替乘)

26.3 数据变换

  1. 用整型而不是浮点
  2. 数组维度尽可能的少
  3. 减少对数组的访问
  4. 使用辅助索引
  5. 使用缓存

26.4 表达式

利用代数恒等式
!a && !b = !(a || b)
编译器初始化
用近似值代替求值
位移
使用一致的类型
预求值
去掉公共子表达式

26.5 子程序

  1. 子程序内联(现代JAVA一般会自动优化该操作)

26.6 用低级语言重写代码

26.7 变得越多,事情反而没变

可读性、可维护性优先

第27章 程序规模对构建的影响

结构

27.1 交流和规模
27.2 项目规模的范围
27.3 项目规模对错误的影响
27.4 项目规模对生产率的影响
27.5 项目规模对开发活动的影响

其他章节关联

软件构建的前期准备 3章
辨明确定你所从事的软件类型 3.2节
管理构建 28章

思考&收获

这一章是一些统计数据。
一句话总结:软件构建工作量跟项目规模近似线性,其他活动非线性加速增长

笔记

27.1 交流和规模

人数越多,交流越复杂

27.2 项目规模的范围

27.3 项目规模对错误的影响

27.4 项目规模对生产率的影响

27.5 项目规模对开发活动的影响

第28章 管理构建

结构

28.1 鼓励良好的编码实践
28.2 配置管理
28.3 评估构建进度表
28.4 度量
28.5 把程序员当人看
28.6 管理你的管理者

其他章节关联

软件构建的前期准备 3章
辨明你所从事的软件类型 3.2节
程序规模 27章
软件质量 20章

思考&收获

看了程序员如何分配时间这栏,我再一次深刻的理解了时间管理的重要性。

笔记

28.1 鼓励良好的编码实践

设置标准
良好的编码实践:

  1. 每个部分分配两个人
  2. 逐行复查
  3. 要求代码签名
  4. 安排好的示例代码供参考
  5. 强调代码是公共财产
  6. 奖励好的代码
  7. 一份简单的标准

28.2 配置管理

配置管理:需求、软件变更控制

需求和设计变更

  1. 遵循某种系统化的变更控制手续
  2. 成组的处理变更请求
  3. 评估每项变更的成本
  4. 提防大量的变更请求
  5. 成立变更委员会
  6. 警惕官僚主义

软件变更

版本控制

机器配置

备份计划

28.3 评估构建进度表

评估方法

  1. 建立目标
  2. 为评估留出时间和计划
  3. 清楚说明软件需求
  4. 在底层细节层面评估
  5. 使用多种评估方法,并比较
  6. 定期做重新评估

进度落后

RSQC:时间、进度、质量、成本

  1. 希望能赶上
  2. 扩充团队
  3. 缩减项目范围

28.4 度量

  1. 留心度量的副作用
  2. 不要反对度量

28.5 把程序员当人看

程序员的时间
个体能力差异很大
物理环境

编码信仰

缩进风格等
如何应对:

  1. 要清楚地知道这是一个敏感问题
  2. 使用“建议”或“指导原则”,避免规则或标准
  3. 避免流露明显的意图:可以通过工具处理
  4. 让程序员自己制定标准

28.6 管理你的管理者

第29章

结构

29.1 集成方式的重要性
29.2 集成频率-阶段还是增量
29.3 增量集成策略
29.4 Daily Build与冒烟测试

其他章节关联

开发者测试 22章
调试 23章
管理构建28章

思考&收获

笔记

29.1 集成方式的重要性

29.2 集成频率-阶段还是增量

阶段式集成

开发-集成-测试

增量集成

益处:

  1. 易于定位错误
  2. 及早取得系统级成果
  3. 改善对进度的监控
  4. 改善客户关系
  5. 更加充分的测试
  6. 更快的构建出整个系统

29.3 增量集成策略

自顶向下集成

自底向上集成

三明治集成

风险导向集成

功能导向集成

T型集成

29.4 Daily Build与冒烟测试

  1. 每日构建
  2. 每日冒烟测试
  3. 及时更新冒烟测试
  4. 自动化
  5. 成立build小组
  6. 按功能持续集成
  7. 提交代码前先冒烟测试
  8. 准备代码分支
  9. 惩罚破坏db的人
  10. 在早上发布build
  11. 有进度压力时也要进行

第30章

结构

30.1 设计工具
30.2 源代码工具
30.3 可执行码工具
30.4 工具导向的环境
30.5 打造自己的编程工具
30.6 工具幻境

其他章节关联

版本控制工具 28.2节
调试工具 23.5节
测试支持工具 22.5节

思考&收获

笔记

30.1 设计工具

30.2 源代码工具

集成开发环境

  1. search&replace
  2. diff
  3. merge
  4. 代码格式化
  5. 生成文档
  6. 模版
  7. 交叉引用
  8. 类的继承体系生成

分析代码质量

  1. 语法检查和语义分析
  2. 复杂性分析

重构代码

  1. 重构器
  2. 结构改组工具
  3. 代码翻译器

版本控制

数据字典

30.3 可执行码工具

产生目标码

  1. 编译器和链接器
  2. Build工具
  3. 程序库
  4. 代码生成向导
  5. 安装
  6. 预处理器

调试

测试

代码调整

执行剖测器
汇编和反汇编

30.4 工具导向的环境

30.5 打造自己的编程工具

30.6 工具幻境

第31章 布局和风格

结构

31.1 基本原则
31.2 布局技术
31.3 布局风格
31.4 控制结构的布局
31.5 单条语句的布局
31.6 注释的布局
31.7 子程序的布局
31.8 类的布局

其他章节关联

自说明的代码 32章
代码格式化工具 30.2节

思考&收获

笔记

31.1 基本原则

把布局作为信仰

  1. 准确表现代码的逻辑结构
  2. 始终如一地表现代码的逻辑结构
  3. 改善可读性
  4. 经得起修改

31.2 布局技术

分组
空行
缩进

31.3 布局风格

31.4 控制结构的布局

要点

  1. 不要用未缩进的begin-end对
  2. 别让begin和end两次缩进
  3. 段落间要空行单语句代码块格式统一
  4. 复杂表达式,条件分隔展示
  5. 不用goto
  6. Case不要有行尾布局的例外。

31.5 单条语句的布局

80字符长度
使用空格
使续行明显
把紧密关联的元素放一块
子程序调用的后续行缩进
让后续行容易发现
将控制语句后续行标准缩进
不要将赋值语句等号对齐
不在一行有有多个操作

  • 数据声明

每行只声明一个数据
变量尽量靠近首次使用
合理组织声明顺序

31.6 注释的布局

  1. 注释缩进一致
  2. 注释与用空行分开

31.7 子程序的布局

  1. 用空行分隔子程序的各部分
  2. 将子程序的参数按标准缩进

31.8 类的布局

  1. 如果文件包含多个类,清楚地标出
  2. 一个文件应只有一个类
  3. 文件命名与类名有关
  4. 在文件中清晰分隔子程序
  5. 按字母顺序排列子程序

第32章

结构

32.1外部文档
32.2编程风格作文档
32.3注释或不注释
32.4高效注释之关键
32.5注释技术
32.6IEEE标准

其他章节关联

布局 31章
伪代码编程过程 9章
可以工作的类 6章
高质量的子程序 7章
编程是交流过程 33.5节 34.3节

思考&收获

笔记

32.1外部文档

  1. 单元开发文件夹
  2. 详细设计文档

32.2编程风格作文档

32.3注释或不注释

种类:

  1. 重复代码
  2. 解释代码
  3. 代码标记
  4. 概述代码
  5. 代码意图说明
  6. 传达代码无法表述的信息

32.4高效注释之关键

  1. 采用不会打断或抑制修改的注释风格
  2. 用伪代码编程法减少注释时间
  3. 将注释集成到开发风格中
  4. 性能不是逃避注释的好借口

32.5注释技术

  • 单行:

不要随意添加无关注释

  • 段:

注释应表达代码意图
代码本身应尽力做好说明
注重why
用注释为后面的内容做铺垫
让每个注释有用
说明非常归做法
别用缩略语
将主次注释分开
错误或语言环境独特点加注释
给出违背良好编程风格的理由
不要注释投机取巧的代码,应重写

  • 数据:

注释单位
注释范围
注释编码含义
注释限制
注释位标志
通过变量名关联注释
注释全局数据

  • 控制结构

每个控制结构加注释

  • 子程序

注释应靠近说明代码
用一两句话说明
注释参数
利用javadoc之类的工具
分清输入输出
注释接口假设
注释局限性
说明子程序的全局效果
记录所有算法的来源
用注释标记程序的各部分

说明设计方法
局限性和假设
注释类接口
不要说明实现细节

  • 文件

说明文件意图和内容
注明作者
包含版本控制标记
请在注释块中包含法律通告
将文件命名与其内容相关的名字

32.6IEEE标准

第33章 个人性格

结构

33.1 个人性格是否和本书话题无关
33.2 聪明和谦虚
33.3 求知欲
33.4 诚实
33.5 交流和合作
33.6创造力和纪律
33.7 懒惰
33.8 不如你想象中的那样起作用的性格因素
33.9习惯

其他章节关联

软件工艺话题 34章
复杂度5.2节 19.6节

思考&收获

笔记

33.1 个人性格是否和本书话题无关

有决定性的意义

33.2 聪明和谦虚

谦卑的空

33.3 求知欲

在开发中建立自我意识
试验
阅读解决问题的方法(框架思维)
在行动前做分析和计划(决策和目标管理)
学习成功项目的开发经验
阅读文档
阅读其他书本期刊
同专业人士交往
向专业开发看齐

33.4 诚实

33.5 交流和合作

33.6创造力和纪律

原则

33.7 懒惰

宁愿花几个钟头做一些其实不必要的工作。中枪。

33.8 不如你想象中的那样起作用的性格因素

别硬干。
别死磕。
更新。
别狂热。

33.9习惯

内隐。

第 34章 软件工艺话题

结构

34.1 征服复杂性
34.2 精选开发过程
34.3 首先为人写程序,其次才是机器
34.4 深入一门语言去编程,不浮于表面
34.5 借助规范集中注意力
34.6 基于问题域编程
34.7 当心落石
34.8 迭代,反反复复,一次又一次
34.9 汝当分离软件与信仰

其他章节关联

思考&收获

笔记

34.1 征服复杂性

34.2 精选开发过程

34.3 首先为人写程序,其次才是机器

自说明的代码

34.4 深入一门语言去编程,不浮于表面

坚持规范

34.5 借助规范集中注意力

34.6 基于问题域编程

划分抽象层次,隐藏实现细节:

  1. 操作系统
  2. 编程语言结构和工具
  3. 低层实现结构
  4. 底层问题域
  5. 高层问题域

34.7 当心落石

34.8 迭代,反反复复,一次又一次

34.9 汝当分离软件与信仰

别非要坚持某种方法。
别把手段当目的。

第35章 何处有更多信息

结构

35.1 关于软件构建的信息
35.2 构建之外的话题
35.3 期刊
35.4 软件开发者的阅读计划
35.5 参加专业的组织

其他章节关联

思考&收获

笔记

35.1 关于软件构建的信息

《Pragmatic Programmer》
《Programming Pearls》
《Extreme Programming Explained:Embrace Change》
《Writing Solid Code- Microsoft's Techniques-for Developing Bug-Free C Software》
《The Practice of Programming》
《Programmers at Work》

35.2 构建之外的话题

  • 综述

《Facts and Fallacies of Software Engineering》
《Professional Software Development》
《The Psychology of Computer Programming》
《程序开发心理学》
《Software Creativity》

  • 软件工程

《Software Engineering: A Practitioner's Approach》
《Software Engineering》,Ian Sommerville

  • 其他

《ACM Computing Reviews》

35.3 期刊

初级技术杂志
《Software Development》
《Dr. Dobb's Journal》
高阶
《IEEE Software》
《IEEE Computer》
《Communications of the ACM》

  • 专业出版物

www.computer.org
www.acm.org

  • 一般

www.sys-con.com/java

35.4 软件开发者的阅读计划

  • 入门级

《Conceptual Blockbusting:A guide to Better Ideas》
《Programming Pearls》
《Facts and Fallacies of Software Engineering》
《Software Project Survival Guide》
《Code Complete》

  • 熟练级

《Software configuration management patterns:effective teamwork, practical integration》
《UML Distilled:A brief guide to the standard Object modeling language》
《software creativity》
《testing computer software》
《applying uml and patterns:an introduction to object-oriented analysis and design and the unified process》
《rapid development》
《software requirements》
《Manager's handbook for software development》NASA

  • 专业级

Software architecture in practice
Refactoring: improving the design of existing code
Design patterns
Principles of software engineering management
object-oriented software construction
Software measurement guidebook

35.5 参加专业的组织

www.computer.org
www.acm.org

Comments
Write a Comment