第3章三思而后行:前期准备上(代码大全7)

第3章 Measure Twice, Cut Once:Upstream Prerequisities 三思而后行:前期准备

  • 3.1 前期准备的重要性
  • 3.2 辨明你所从事的软件的类型
  • 3.3 问题定义的先决条件

3.1 Importance of Prerequisites 前期准备的重要性

如果你在项目的末期强调质量,那么你会强调系统测试。但是测试只是完整的质量保证策略的一部分,而且不是最有影响的部分。测试是不可能检查出诸如:“制造了一个错误的产品”,或者“使用错误的方法制造正确的产品”之类的缺陷的。这样的缺陷在测试之前解决——更确切地说是在构建活动之间。

如果你在项目中期强调质量,那么你就会强调构建实践。这些实践是本书绝大部分篇幅的关注点

如果你在项目的开始阶段强调质量,那么你就会计划、要求并且设计一个高质量的产品。

  • Do Prerequisites Apply to Modern Software Projects

前期准备适用于现代软件项目吗

有些人断言,诸如架构、设计及项目规划等前期工作对于软件项目来说是毫无用处的。总体来说,没有哪项研究(无论过去还是仙子阿)支持这一断言,最近的数据也不支持这一断言。

准备工作的中心目标就是降低风险:一个好的项目规划者能够尽可能早地将主要的风险清除掉,以使大部分工作能够尽可能平稳地进行。目前,软件开发中最常见的项目风险是糟糕的需求分析和糟糕的项目计划,因此准备工作就倾向于集中改进需求分析和项目规划。

  • Causes Of IncompletePreparation

准备不周全的诱因

造成准备工作不充分的一个常见的原因是,那些分配去做前期准备活动的开发人员并不具备完成这一任务的专业技能。当开发人员不知道如何进行这些前期工作的时候,建议“做更多的前期工作”就完全没有用:如果不能首先把这项工作做好,那么做再多也没有意义!

有一些程序员确实知道如何进行前期工作,但是他们并没有做,因为他们不能够抵抗“尽快开始编码”的欲望。如果你也是这样,我有两条建议:第一:阅读下一节中的争论,它也许能告诉你一些你以前没有想到的问题;第二,注意一下你经历过的问题。只需要做几个大项目,你就能体会到:事先做好计划能避免很多压力。

程序员不做准备工作的最后一个原因是,管理者们队那些“花时间进行构建活动的前期准备的程序员”的冷漠已经到了人神公愤的程度。你可以期望,管理着们应该已经开始明白:软件开发不仅仅是写代码。

  • Utterly Compelling and Foolproof Argument for Doing Prerequisites Before Construction

关于开始构建之前要做前期准备的绝对有力且简明的论据

Appeal to Logic 诉诸逻辑

进行有效编程的要领之一是:准备工作很重要。在开始做一个大项目之前,应该为这个项目制定计划,这是很有意义的。从管理的角度看,做计划意味着确定项目所需要用的时间、人数以及计算机台数。从技术角度讲,做计划意味着弄清楚你想要建造的是什么,以防止浪费钱去建造错误的东西。有时候用户在一开始并不完全清楚自己想要的是什么,因此值得花费比理想情况下更多的力气,找出他们真正想要的东西。但这至少比“先做一个错误的东西出来,然后扔掉,并从头来过”的成本要低廉

在开始动手制作这个系统之前,先好好思考打算如何去做,这也非常重要。你总部希望花费很多的时间和金钱,却毫无必要地走进死胡同(尤其当这样做会增加成本的时候)

Appeal to Analogy 诉诸类比

程序员是软件食物链的最后一环。架构师吃掉需求,设计师吃掉架构,而程序员则消化设计。

Appeal to Data 诉诸数据

过去25年来的研究确凿地证明了,在一开始就把事物做好是最合算的。进行非必要的改动的代价是高昂的。

Boss-Readiness Test “老板就绪”测试

如果你的老板已经明白了“在开始构建之前进行前期准备”的重要性,那么试试以下的测试,以确保他确实明白了。

下面的句子哪些是自我实现的语言(sel-fulfilling prophecies)

  • 我们最好立刻开始编码,因为将会有很多的调试工作需要去做。
  • 我们并没有为测试安排太多的时间,因为将来不会发现多少缺陷
  • 我们已经非常详细地研究了需求和设计,我想不出在编码和调试期间还会遇到什么大的问题

上面这些陈述都是自我实现的语言,要瞄准最后那个。

3.2 Determine the Kind of Software You‘re Working on 辨明你所从事的软件的类型

软 件 种 类
  商业系统 使命攸关的系统 性命攸关的嵌入式系统
典型应用 Internet站点
Intranet站点
库存管理
游戏
游戏
管理信息系统(MIS)
工资系统
嵌入式软件
游戏
Internet站点
盒装软件
软件工具
Web service
航空软件
嵌入式软件
医疗设备
操作系统
盒装软件
生命周期模型 敏捷开发(极限编程,Srum, time-box, 开发等等)
渐进原型(prototyping)
分阶段交付
渐进交付
螺旋式开发
分阶段交付
螺旋式开发
渐进交付
计划与管理 增量式项目计划
随需测试与QA计划
非正式的变更控制
基本的预先计划
基本的测试计划
随需QA计划
正式的变更控制
充分的预先计划
充分的测试计划
充分的QA计划
严格的变更控制
需求 非形式化的需求规格 半形式化的需求
随需的需求评审
形式化的需求规格
形式化的需求检查
设计 设计与编码时结合的 架构设计
非形式化的详细设计
随需的设计评审
架构设计
形式化的架构检查
形式化的详细设计
形式化的详细设计检查
构建 结对编程或独立编码
非正式的check-in手续或没有check-in手续
结对编程或独立编码
非正式的check-in
随需代码评审
结对编程或独立编码
正式的check-in手续
正式的代码检查
测试与QA 开发者测试自己的代码
测试先行开发
很少或没有测试(由单独的测试小组来做)
开发者自己测试自己的代码
测试先行开发
单独的测试小组
开发者测试自己的代码
测试先行开发
单独的测试小组
单独的QA小组
部署 非正式的部署过程 正式的部署过程 正式的部署过程
  • Iterative Approaches‘ Effect on Prerequisites

迭代开发对前期准备的影响

迭代方法往往能够减少“前期准备不足”造成的负面影响,但是它不能完全消除次影响。

  • Choosing Between Iterative and Sequential Approaches

在序列式开发法和迭代式开发法之间做出选择

你可能因为下列原因选择一个更加序列化的方法

  • 需求相当文档
  • 设计直接了当,而且理解透彻
  • 开发团队对于这一应用领域非常熟悉
  • 项目的风险很小
  • "长期可预测性"很重要
  • 后期改变需求、设计和编码的代价可能较昂贵

你可能因为下列原因选择一个更加迭代(as you go,走着瞧)的方法

  • 需求并没有被理解透彻,或者处于其他理由你认为它是不稳定的
  • 设计很复杂,或者有挑战性,或者两者兼具
  • 开发团队对于这一应用领域不熟悉
  • 项目包含许多风险
  • “长期可预测性”不重要
  • 后期改变需求,设计和编码的代价很可能较低

事实上,在软件开发中,适用迭代开发法的情况比使用序列开发法的情况多得多。你应该首先确定哪些前期准备活动适合你的项目。有些项目在前期准备上面花的时间太少了,结果使得在构建活动中遇到大量不必要的反复修改,同时阻碍了项目的稳步前进。有些项目则预先作了太多的事情,固执地坚持原有的需求和计划,后来事实证明这些需求和计划是无效的,这同样阻止了构建活动的顺利进展。

3.3 Problem-Definition Prerequisite 问题定义的先决条件

在开始构建之前,首先要满足的一项先决条件是,对于这个系统要解决的问题作出清楚的陈述

问题定义应该用客户的语言来书写,而且应该从客户的角度来描述问题。通常不应该用计算机的专业术语叙述。这条规则也有例外,那就是解决的就是与计算机本身相关的问题:编译时间太长,或者开发工具bug太多。这种情况下使用计算机术语或程序员术语来陈述问题是恰当的。

"未能定义问题"的处罚是,你浪费了大量时间去解决错误的问题。这是双重处罚,因为你也没有解决正确的问题

时间: 2024-10-30 05:36:20

第3章三思而后行:前期准备上(代码大全7)的相关文章

第33章个人性格(代码大全5)

第33章 Personal Character 个人性格 33.1 个人性格是否和本书话题无关 33.2 聪明和谦虚 33.3 求知欲 33.4 诚实 33.5 交流与合作 33.6 创造力和纪律 33.7 懒惰 33.8 不如你想象中那样其作用的性格因素 33.9 习惯 33.1 Isn't Personal Character Off The Topic 个人性格是否和本书话题无关 编程过程非常耗用脑力,这种特性使得个人性格显得很重要.编程工作本质上是项无法监督的工作,因为没人真正清楚你正在

第四章关键的构建决策(代码大全2)

一旦你能确定 “构建”的基础已经打好,那么准备工作就转变为针对特定“构建”的决策了.第3章“三思而后行:前期准备”讨论了设计蓝图和建筑许可证在软件业务里的等价物.你可能对那些准备工作没有多少发言权,所以在第3章关注的焦点是确定“当构建开始后你需要做什么”.本章关注的焦点是程序员和技术带头人个人必须(直接或间接)负责的准备工作.在向工地进发之前,如何选择适用的工作别在你的腰带上,你的手里车里应该装哪些东西?本章讨论的就是这事务在软件中的等价物. 4.1 选择编程语言(Choice of Progr

第3章三思而后行:前期准备下(代码大全8)

第3章 Measure Twice, Cut Once:Upstream Prerequisities 三思而后行:前期准备 3.4 需求的先决条件 3.5 架构的先决条件 3.6 花在前期准备上的时间长度 要点 3.4 Requirements Prerequisite 需求的先决条件 软件架构(software architecture)是软件设计的高层部分,是用于支撑更细节的设计的框架. 为什么要把架构作为前期准备工作呢?因为架构的质量决定了系统的“概念完整性”.后者继而决定了系统的最终质

第8章防范式编程上(代码大全3)

防御式编程并不是说让你在编程时持“防备批评或攻击”的态度——“它就是这么工作!”这一概念来自防御式驾驶.在防御式驾驶中要建立这样一种思维,那就是你永远也不能确定另一位司机将要做什么.这样才能确保其他人在做出危险动作时你也不会受到伤害.你要担负起保护自己的责任,哪怕是其他司机犯的错误.防御式编程的主要思想是:子程序应该不因为传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据.更一般地说,其核心是要承认程序都会有问题,都需要被修改,聪明的程序员应该根据这一点来编程序. 8.1 Protectin

第8章防范式编程下(代码大全4)

8.4 Exceptions 异常 用异常通知程序的其他部分,发生了不可忽略的错误 只在真正例外的情况下才抛出异常 不能用异常来推卸责任 避免在构造函数和析构函数中抛出异常,除非你在同一地方把它们捕获 在恰当的抽象层次抛出异常 在异常消息中加入关于导致异常发生的全部信息 避免使用空的catch语句 了解所用函数库可能抛出的异常 考虑创建一个集中的异常报告机制 把项目中对异常的使用标准化 对于像C++这类语言,其中允许抛出多种多样的对象.数据及指针的话,那么就应该为到底可以抛出哪些类的异常建立一个

《代码大全》读书笔记(上)

对于书中提到的一点印象最为深刻, 其实在 <人月神话>也有提到, 那就是: 软件设计与开发的核心就在于 控制复杂度 这句话的核心其实包括几个问题: 软件开发的本质问题性难题是 复杂度 ? 如何可以一定程序的降低复杂度 ? 其中, 书中对于软件设计必须控制复杂度的解释原因是: 没有谁的大脑能容得下一个现代计算机程序, 也就是输,  我们不应该试着在同一时间把整个程序都塞进自己的大脑, 而应该试着以某种方式去组织程序, 以便能在同一个时刻可以专注于一个地方. 这么做的目的是尽量减少同一时间所要考虑

初读《代码大全》

对于<代码大全>这本书我还没有仔细的读,更别说是看完了,我就重点看了一下第三.四章,主要讲软件工程的前期准备,其次就是我大致浏览了一下后面的内容.第一感觉就是作者写得相当好,插入了不少段子,比喻形象,生动诙谐.但是没有深入的研读难以给出有意义的问题,想问题快把我想得头都要爆炸了,最终还挤出了几个问题.虽然本书主要讲的是软件构建过程,下面的问题主要集中在软件架构相关的领域.1字符集总是让人捉摸不透,那么常用的编程语言都分别支持哪些字符集,如何用这种语言编写制定字符集的程序?字符串类型和字符集类型

《代码大全2》读后感czz

经老师推荐,买了一本<代码大全2>,花了近3个月的时间看完了,看完后觉得还有很多值得回味的地方,而且每部分之后作者还推荐了不少经典书籍.所以,作个读书心得.全书的主题是软件构建,关于软件构建问题的方方面面均有涉及,共分7个部分,从软件构建前期准备,到语言层的一些问题,再到代码完善,系统考虑以及软件工艺等等.以下分别进行简单说明. 第一部分是打好基础,本部分主要是软件构建前期的工作,以及对一些基本概念的介绍,具体包括如何选择编程语言和构建实践方法,如何理解软件开发的过程.软件开发本质上说就是工程

《代码大全》读后有感

原本是为了完成软件工程课的作业任务,才打开了这么一本大部头的著作.虽然这一周只读了几章,但是却觉得第一次这样认真的将软件与代码区别开来,也是第一次以工程的角度考虑软件.虽然上了“软件工程”这样的课程,但一来上课不认真,二来课程内容经常纠结于局部问题,所以没有感觉.想来这门课的老师也知道这样的情况,所以第一堂课就说明要我们找些这方面的著作看.然而...还是没能引起我们的重视. 直到上周这个时候,说道要检查博客,才想起这回事.原本想随便找本薄些的书看看,但又想着,要看还是看些经典,于是找到了<代码大

代码大全阅读笔记(二)

代码大全这本书只看懂了一部分,现只对最有收获的部分写入笔记里 第七章 创建子程序的正当理由 (1)降低复杂度;(2)避免代码充分;(3)支持子类化;(4)隐藏顺序;(5)隐藏指针操作;(6)提高可移植性;(7)简化复杂的布尔判断;(8)改善性能 对于过于简单的代码写成子程序的两大理由:1 可以增加程序的可读性 2简单程序可能变成复杂程序 1 在子程序层上设计 内聚性强调把一件事做好,不再做其它任何事情这样做的好处是得到更高的可靠性 顺序上的内聚性是指在子程序内包含有需要按特定顺序执行的操作,这些