《人月神话》(P11)为舍弃而计划

实验性工厂和增大规模

  • 化学工程师很早就意识到:在某个化学反应大规模投产之前必须进行实验性的生产。
  • 软件系统的构建人员也面临同样的问题,但似乎从来没有吸取教训。总是设计、应用、然后把第一次开发的产品交付给客户。
  • 对于大多数项目,第一次开发的系统并不合用,必须要不断的开发更好的系统。
  • 即便最优秀的项目经理,也不能完全知晓并解决问题。新的技术和概念总会不断的出现在项目中,所以我们必须构建一个用来抛弃的系统。
  • 不要考虑,“我们是否应该构建一个实验性系统”,因为这一定是必要的。我们应该问“是否需要将原型展示给用户”。
  • 将原型展示给客户的有点是:可以获取时间。但代价是:用户使用体验不佳,分散开发者精力,影响产品形象。

唯一不变的是变化本身

  • 软件系统的变化是与生俱来的,并不是不合时宜的令人厌恶的异常情况。
  • 开发人员交付的是用户满意度,而不是有形的产品。
  • 用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化。
  • 实体产品阶段化了用户对于变更的需求,然而软件产品的不可见性,导致它的构建人员面临永恒的需求变更。
  • 并不推荐将所有的可能变化都整合到设计阶段中。目标上的变化是不可避免的,甚至技术上、策略上的变化也不可避免。
  • 必须学会接受事实,不断的学习,不断地更改设计。

为变更而设计系统

  • 如何为变化设计系统是一个老生常谈的问题。方式包括:模块化、可扩展的函数、接口设计、文档编写。最重要的措施是使用更高级语言。
  • 必须为变更划分出阶段,每个产品都有自己的数字编号,每个版本都有属于自己的日程表,在此之后的变更属于下一个版本的范畴。

为变更而计划组织结构

  • 为变更组件团队要比为变更进行设计更加困难。从技术角度而言,整个团队都可以被灵活的安排。
  • 管理人员和技术人才需要具有互换性,这其中的障碍是社会性的。贝尔实验室采用了废除所有头衔的方式,让每个专业人士都是技术人员中的一员。
  • IBM 采用双线的模式管理项目人员。从技术线向管理线调动时,不能伴随着待遇的提升,应当称之为“调动”而不是“晋升”。
  • 管理人员与开发人员待遇相同,这对传统的意识是一种改变。
  • 高级人员在参与编程开发时,不会感到自降身份,消除了社会障碍。

前进两步,后退一步

  • 在程序发布给顾客使用之后,并不会停止变化。发布后的变更被称为“程序维护”,但是对于软件的维护过程不同于硬件维护。
  • 软件维护主要包含对设计缺陷的修复。软件维护的变更通常包含了更多的新增功能,通常是用户能够察觉的。
  • 对于一个广泛使用的程序,其维护总成本总是开发成本的40%或更多。用户越多,所发现的错误就越多。
  • 软件生命周期中有一个有趣的循环:发现 bug 的数量随着时间的变化,会先由多变少,再由少变多。可以理解为用户达到一定熟练水平之后,就会开始运用新的功能。
  • 每一次修复缺陷,总有20%~50%的概率引入新的错误,这就是走两步后,退一步。
  • 看上去很微小的错误,似乎仅仅是局部操作上的失败,实际上却是系统级别的问题。
  • 理论上,每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。然而,实际情况中这样回归测试的成本非常高。
  • 显然,使用能够直观看到副作用的程序设计方法,将带来巨大收益。另外,越简单,错误越少。

前进一步,后退一步

  • 程序的模块总数总是随着版本号的增长而线性增长,然而受到影响的模块数量却成指数增长。所有的修改都倾向于破坏系统的架构,增加了系统的混乱程度。
  • 修复早期设计引发的漏洞的工作越来越少,而维护工作本身引起的漏洞修复工作却越来越多。
  • 老的系统尽管在理论上一直可用,但实际上已经面目全非,无法再继续成为下一步发展的基础。
  • 用户的需求永远在变化,系统却不能一直可用。一个崭新的、基于原有系统的重新设计是完全必要的。
  • “事物在最初总是最好的”。
  • 软件的开发是减少混乱程度的过程,他本身是平稳的。软件维护是提高混乱度的过程,即使是最熟练的软件维护工作,也只是放缓了系统变得不稳定的进程。

以上就是《人月神话》第10章——未雨绸缪的所有内容

本章中作者开篇引用了一句名言“不变只是愿望,变化才是永恒”,以此引出软件行业中一个重要的概念,那就是开发必须要面向变更。这不是对于开发人员的要求,而是客观上任何软件系统的规律,甚至于对于开发团队的配置都要求可以灵活变更。

作为一名软件外包行业的从业者,对本章的感触的很深的,外包的痛点之一就是客户在整个开发过程中对于需求的变化是随时都可能发生的,时间越长变化的可能性就越大,所产生变化的点也就越多。虽然通过各种开发文档能够将部分风险转移到甲方,但转移的同时甲方对于开发的体验也就变差了。

而开发人员的目的其实是交付“用户满意度”,这就导致了无论前期有多么完善的文档(大部分项目根本达不到完善的程度),只要发生了需求变化,用户满意度总是下降的。一旦下降到一定程度,很可能会再次反作用于项目本身,导致更多的修改。这种情况也就意味着项目整体是失败的了。

通常我们会采用下面的方法来尝试摆脱困局:

  • 将项目拆分成不同的阶段,分开交付。对于功能复杂的项目,就考虑将某些相对独立的功能拆分开来。所交付的功能越少,对项目的把握就越大。
  • 让开发时间尽可能的短,也就是让开发人员尽可能的加快开发的进度,开发之前一定要整理好相关的需求文档。
  • 使用已经稳定运行的代码,也就是采用二次开发的方式,或者叫换壳开发。

对于公司来说这些确实是最容易想到,也行之有效的方法。但是,如果换一个角度思考,例如我们把项目开发过程中涉及到的人员拆分成三个部分,情况则完全是相反的。这三个部分分别是:

公司、开发团队、客户

之所以可以这么分是因为各个部分所代表的利益都不同,公司代表的是成本和收益,开发团队代表的是效率和薪资,客户代表的是满意程度。

  • 我们将项目拆分时,依据的是公司行业经验。对于开发团队来说由于二期、三期的目标不明确,在系统设计阶段难免会出现考虑不周,导致后续开发成本增加,甚至难以进行继续迭代。对于客户来说,将会难以理解各个阶段所产生的成本,很容易出现“我只是加个功能,为什么成本这么高”的感觉。

  • 缩短开发时间,意味着开发过程中的沟通是几乎没有的,客户在初期往往是无法将所有的需求都表达清楚的,交付过程会显得突兀。开发团队也因此增加了工作量,开发团队也是需要工作体验的,压榨周期会让团队变得消极。

  • 小型项目进行二次开发是很好的方式,但对于大型项目(特别是定制项目)则完全等于是在碰运气。在甲乙双方本身沟通就不太流畅的情况下,还引入了另一个需要照顾的方面,那就是原有的项目,矛盾很容易被放大。

所以说这些很容易想到的对策,其实在三方利益的博弈中只满足了公司一方。这也是为什么外包公司的开发团队远比互联网公司的开发团队体验差的原因了(互联网公司和其开发团队往往代表的是相同利益)。

所以正确的方式应该是怎样的呢?

在博弈论中有一个叫做“坏孩子”的理论,说的是如果父亲无条件的对所有孩子好,那么只需要每一个孩子保持“自私”,整个家庭的利益将会最大化。如果包括父亲在内的每一个成员都保持“自私”,就会伤害到善良的那个孩子,导致总体家庭利益无法达到最大。

公司在这之中所担任的角色其实是类似于父亲的,甚至可以把成员再细分为:公司、客户、开发人员、设计人员、首席开发人员、售前经理、程序秘书等等,各自代表着不同的利益。只要公司愿意对其他人员保持无私的付出,整个系统是完全有可能达到最大利益平衡的。

有点说远了。

上述的团队是如何解决“变化才是永恒”的问题的呢?

  • 对售前阶段进行成本核算
  • 对客户进行培训
  • 提高开发团队配置
  • 沉淀公司制度

在竞争市场中,售前成本核算是最难迈出的一步,客户对此的接受程度有可能是极低的。虽然没有调查过,但是市场上大量的“模板项目”、“价格战”,让客户对于收费是很敏感的。其次,客户本身对于软件行业的了解就不足,很难理解他所购买的“售前服务”到底是什么。即便如此,我依然认为这是可行的解决方法,因为它的影响很大。

售前成本核算意味着客户能够得到高质量的售前服务,高质量的售前服务意味着需要安排经验丰富的工程师,经验丰富的工程师意味着项目的“概念完整性”将得到保证,概念完整性意味着项目的高质量,高质量意味着高报价,高报价意味着优秀的开发团队介入,优秀的团队意味着交付更高的“用户满意度”。

又说远了,其实我能想到的这些方法,目前也都处于寻求“自洽”的阶段。还有三个方法,可能随着《人月神话》的深入会进一步的思考。

自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

你可能感兴趣的:(《人月神话》(P11)为舍弃而计划)