《软件开发的201个原则》

2022/2/4

#

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

  • 描述需求规格最好的方法是:
    1. 先写自然语言
    2. 写形式化语言
    3. 根据形式化模型中发现的问题去修改自然语言,以减少歧义

原则55:在更形式化的模型前,先写自然语言

THEOREM

  • 无效的可靠性:这个系统有99.99%的可靠性
  • 正确的表达:
    1. 需求失效:系统应正确报告99.99%的病人生命体征异常
    2. 失败率:系统报告不准确的次数,每年不超过一次
    3. 可用性:电话系统在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:系统存在促进了演变
上次更新: 11/1/2024