# 序
We all have the same responsibility today we had 50 years ago,to use our best knowledge to build the safest,most reliable,least vulnerable systems we are capable of.
THEOREM
我们今天肩负着和50年前相同的责任,即,使用我们拥有的最好的知识来构建我们有能力构建的最安全、最可靠、最稳定的系统。
THEOREM
软件开发的方法论和基本原则,并不像语言和工具领域那样活跃,它们都没有明显的变化。
THEOREM
好的软件工程师和差的软件工程师研发效率可能差25倍,质量可能差10倍。软件工程师并不是『新时代农民工』,而是高科技脑力工作者。
THEOREM
对于一个软件工程师,具备正确的意识比掌握具体的知识更重要。
章淼
书籍推荐
- code complete《代码大全》
- programming pearls《编程珠玑》
- rapid development
# 一般原则
- 原则1:质量第一
- 原则2:质量在每个人眼中都不同
- 原则3:开发效率和质量密不可分
- 原则4:高质量软件是可以实现的
- 原则5:不要试图通过改进软件实现高质量
- 原则6:低可靠性比低效率更糟糕
- 原则7:尽早把产品交给客户
- 原则8:与客户/用户沟通
- 原则9:促使开发者和客户目标一致
- 原则10:做好抛弃的准备
- 原则11:开发正确的原型
- 原则12:构建合适功能的原型
- 原则13:要快速地开发一次原型
- 原则14:渐进性地扩展系统
- 原则15:看到越多,需要越多
- 原则16:开发过程中的变化是不可避免的
- 原则17:只要有可能,购买/复用而非开发
- 原则18:让软件只需要简短的用户手册
- 原则19:每个复杂的问题都有一个解决方案
- 原则20:记录你的假设
- 原则21:不同的阶段,使用不同的语言
- 原则22:技术优先于工具
- 原则23:使用工具,但要务实
- 原则24:把工具交给优秀的工程师
原则25:CASE工具是昂贵的- 原则26:『知道何时』和『知道如何』同样重要
- 原则27:实现目标就停止
- 原则28:了解形式化方法
- 原则29:和组织荣辱与共
- 原则30:跟风要小心
- 原则31:不要忽视技术
- 原则32:使用文档标准
- 原则33:文档要有术语表
- 原则34:软件文档都要有索引
- 原则35:对相同的概念用相同的名字
- 原则36:研究再转化,不可行
- 原则37:要承担责任
THEOREM
质量必须放在首位,没有可商量的余地。Edward Yourdon建议,当你被要求加快测试、忽视剩余少量BUG、在设计或需求达成一致前就开始编码设计时,要直接说『不』。
原则1:质量第一
THEOREM
对质量要求越高,开发效率就越低。
贝尔实验室发现:在要求每千行有1~2个BUG时,人/月的开发效率通常为100-300行代码。
当试图提高开发效率时,BUG的密度就会增加。
原则3:开发效率和质量密不可分
THEOREM
对于一个项目来说,最关键的成功因素之一,是它所涉及的领域是否是全新的。在全新的领域(可能涉及应用程序、体系结构、接口、算法等)研发的程序很少能第一次就成功。
- 第一个被完整部署的系统,往往是第二个被创建的系统
原则10:做好抛弃的准备
THEOREM
- 有两种原型
- 一次性原型:关键需求特性没有被很好的理解的时候使用。
- 演进式原型:关键特性已被充分理解,但很多其他需求特性还没有被充分理解时使用。
如果对大多数功能都不了解,应该先构建一个一次性原型,然后从零构建一个演进式原型。
原则11:开发正确的原型
THEOREM
作为开发者,应该复用尽可能多的软件。
原则17:只要有可能,购买/复用而非开发
THEOREM
衡量软件系统质量的一种方法是查看其用户手册内容的多少。手册中内容越少,软件质量越好。
原则18:让软件只需要简短的用户手册
THEOREM
一名优秀的工程师了解很多不同种类的技术,并且知道每种技术何时适合项目或项目的一部分。一个好的木匠知道多种工具的用法,知道很多不同的技巧。而且,最重要的是,知道什么时候该用哪一种。
原则26:『知道何时』和『知道如何』同样重要
THEOREM
当你在学习新技术时,不要轻易接受与之相关的不可避免的炒作。要仔细阅读,理性的考虑它的收益和风险。在大规模使用之前要进行试验。但也绝对不要忽视新技术。
原则30:跟风要小心
THEOREM
不要有任何借口。如果你是一个系统开发者,把它做好是你的责任。要承担这个责任。要么做好,要么就压根不做。
原则37:要承担责任。
# 需求工程原则
- 原则38:低质量的需求分析,导致低质量的成本估算
- 原则39:先确定问题,再写需求
- 原则40:立即确定需求
- 原则41:立即修复需求规格说明中的错误
- 原则42:原型可降低选择用户界面的风险
- 原则43:记录需求为什么被引入
- 原则44:确定子集
- 原则45:评审需求
- 原则46:避免在需求分析时进行系统设计
- 原则47:使用正确的方法
- 原则48:使用多角度的需求视图
- 原则49:合理地组织需求
- 原则50:给需求排列优先级
- 原则51:书写要简洁
- 原则52:给每个需求单独编号
- 原则53:减少需求中的歧义
- 原则54:对自然语言辅助增强,而非替换
- 原则55:在更形式化模型前,先写自然语言
- 原则56:保持需求规格说明的可持续性
- 原则57:明确规定可靠性
- 原则58:应明确环境超出预期时的系统行为
- 原则59:自毁的待定项
- 原则60:
将需求保存到数据库
THEOREM
- 如果在需求规格说明中有错误,你将付出以下代价:
- 如果错误保持到系统设计阶段,定位和修复要多花5倍的代价
- 如果保持到编码阶段,要多花10倍的代价
- 如果保持到单元测试的阶段,要多花20倍的代价
- 如果保持到交付阶段,要多花200倍的代价
原则41:立即修复需求规格说明中的错误
THEOREM
- 描述需求规格最好的方法是:
- 先写自然语言
- 写形式化语言
- 根据形式化模型中发现的问题去修改自然语言,以减少歧义
原则55:在更形式化的模型前,先写自然语言
THEOREM
- 无效的可靠性:这个系统有99.99%的可靠性
- 正确的表达:
- 需求失效:系统应正确报告99.99%的病人生命体征异常
- 失败率:系统报告不准确的次数,每年不超过一次
- 可用性:电话系统在99.99%的情况下可用
原则57:明确规定可靠性
# 设计原则
- 原则61:从需求到设计的转换并不容易
- 原则62:讲设计追溯至需求
- 原则63:评估备选方案
- 原则64:没有文档的设计不是设计
- 原则65:封装
- 原则66:不要重复造轮子
- 原则67:保持简单
- 原则68:避免大量的特殊案例
- 原则69:缩小智力距离
- 原则70:将设计置于知识控制之下
- 原则71:保持概念一致
- 原则72:概念性错误比语法错误更严重
- 原则73:使用耦合和内聚
- 原则74:为变化而设计
- 原则75:为维护而设计
- 原则76:为防备出现错误而设计
- 原则77:在软件中植入通用性
- 原则78:在软件中植入灵活性
- 原则79:使用高效的算法
- 原则80:模块规格说明只提供用户需要的信息
- 原则81:设计是多维的
- 原则82:优秀的设计出自优秀的设计师
- 原则83:理解你的应用场景
- 原则84:无需太多投资,即可实现复用
- 原则85:错进错出,是不正确的
- 原则86:软件可靠性可以通过冗余来实现
# 编码原则
- 原则87:避免使用特殊技巧
- 原则88:避免使用全局变量
- 原则89:编写可自上而下阅读的应用程序
- 原则90:避免副作用
- 原则91:使用有意义的命名
- 原则92:程序首先是写给人看的
- 原则93:使用最优的数据结构
- 原则94:先保持正确,再提升性能
- 原则95:在写代码之前先写注释
- 原则96:先写文档后写代码
- 原则97:手动运行每个组件
- 原则98:代码审查
- 原则99:你可以使用非结构化语言
- 原则100:结构化的代码未必是好的代码
- 原则101:不要嵌套太深
- 原则102:使用合适的语言
- 原则103:编程语言不是借口
- 原则104:编程语言的知识没那么重要
- 原则105:格式化你的代码
- 原则106:不要太早编码
# 测试原则
- 原则107:语句需求跟踪测试
- 原则108:在测试之前早做测试计划
- 原则109:不要测试自己开发的软件
- 原则110:不要为自己的软件做测试计划
- 原则111:测试只能揭示缺陷的存在
- 原则112:虽然大量的错误可证明软件毫无价值,但是领错误并不能说明软件的价值
- 原则113:成功的测试应发现错误
- 原则114:半数的错误出现在15%的模块中
- 原则115:使用黑盒测试和白盒测试
- 原则116:测试用例应包含期望的结果
- 原则117:测试部正确的输入
- 原则118:压力测试必不可少
- 原则119:大爆炸理论不适用
- 原则120:使用McCabe复杂度指标
- 原则121:食用油晓得测试完成度标准
- 原则122:达成有效的测试覆盖
- 原则123:不要再单元测试之前集成
- 原则124:测量你的软件
- 原则125:分析错误的原因
- 原则126:对错不对人
# 管理原则
- 原则127:好的管理比好的技术更重要
- 原则128:使用恰当的方法
- 原则129:不要相信你读到的一切
- 原则130:理解客户的优先级
- 原则131:人是成功的关键
- 原则132:几个好手要强过很多生手
- 原则133:倾听你的员工
- 原则134:信任你的员工
- 原则135:期望优秀
- 原则136:沟通技巧是必要的
- 原则137:端茶送水
- 原则138:人们的动机是不同的
- 原则139:让办公室保持安静
- 原则140:人和时间是不可互换的
- 原则141:软件工程师之间存在巨大差异
- 原则142:你可以优化任何你想要优化的
- 原则143:隐蔽的收集数据
- 原则144:每行代码的成本是没用的
- 原则145:衡量开发效率没有完美的方法
- 原则146:剪裁成本估算方法
- 原则147:不要设定不切实际的截止时间
- 原则148:避免不可能
- 原则149:评估之前要先了解
- 原则150:收集生产力数据
- 原则151:不要忘记团队效率
- 原则152:LOC/PM与语言无关
- 原则153:相信排期
- 原则154:精确的成本估算并不是万无一失的
- 原则155:定期重新评估排期
- 原则156:轻微的低估不总是坏事
- 原则157:分配合适的资源
- 原则158:定制详细的项目计划
- 原则159:及时更新你的计划
- 原则160:避免驻波
- 原则161:知晓十大风险
- 原则162:预先了解风险
- 原则163:使用适当的流程模型
- 原则164:方法无法挽救你
- 原则165:没有奇迹般提升效率的秘密
- 原则166:了解进度的含义
- 原则167:按差异管理
- 原则168:不要过度使用你的硬件
- 原则169:对硬件的演化要乐观
- 原则170:对软件的演化要悲观
- 原则171:认为灾难是不可能的往往导致灾难
- 原则172:做项目总结
# 产品保证原则
- 原则173:产品保证不是奢侈品
- 原则174:尽早建立软件配置管理过程
- 原则175:使软件配置管理适应软件过程
- 原则176:组织SCM独立于项目管理
- 原则177:轮换人员到产品保证组织
- 原则178:给所有中间产品一个名称和版本
- 原则179:控制基准
- 原则180:保存所有内容
- 原则181:跟踪每一个变更
- 原则182:不要绕过变更控制
- 原则183:对变更请求进行分级和排期
- 原则184:在大型开发项目中使用确认和验证
# 演变原则
- 原则185:软件会持续变化
- 原则186:软件的熵增加
- 原则187:如果没有坏,就不要修理它
- 原则188:解决问题,而不是症状
- 原则189:先变更需求
- 原则190:发布之前的错误也会在发布之后出现
- 原则191:一个程序越老,维护起来越困难
- 原则192:语言影响可维护性
- 原则193:有时重新开始会更好
- 原则194:首先翻新最差的
- 原则195:维护阶段比开发阶段产生测问题更多
- 原则196:每次变更后都要进行回归测试
- 原则197:『变更很容易』的想法会使变更更容易出错
- 原则198:对非结构化代码进行结构化改造,并不一定会使它更好
- 原则199:在优化前先进行性能分析
- 原则200:保持熟悉
- 原则201:系统存在促进了演变