人月神话(五)未雨绸缪、干将莫邪、整体部分

第11章 未雨绸缪

Part 1 实验性工厂和增大规模

对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。要解决所有的问题,除了重新开始以外,没有其他的办法—即开发一个更灵巧或者更好的系统。系统的丢弃和重新设计可以一步完成,也可以一块块地实现。所有大型系统的经验都显示,这是必须完成的步骤。而且,新的系统概念或新技术会不断出现,所以开发的系统必须被抛弃,但即使是最优秀的项目经理,也不能无所不知地在最开始解决这些问题

Part 2 唯一不变的就是变化本身

一旦认识到试验性的系统必须被构建和丢弃,具有变更思想的重新设计不可避免,从而直面整个变化现象是非常有用的开发人员交付的是用户满意程度,而不仅仅是实际的产品。用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化。

软件产品易于掌握的特性和不可见性,导致它的构建人员面临永恒的需求变更。

不但目标上的变化不可避免,而且设计策略和技术上的变化也不可避免。抛弃原型概念本身就是对事实的接受—随着学习的过程更改设计。

Part 3 为变更计划系统

如何为上述变化设计系统,是个非常著名的问题,在书本上被普遍讨论——可能讨论得比实践还要多得多。

① 包括细致的模块化、可扩展的函数、精确完整的模块间接口设计、完备的文档

② 可能会采用包括调用队列和表驱动的一些技术。

③ 最重要的措施是使用高级语言和自文档技术,以减少变更引起的错误。采用编译时的操作来整合标准声明,在很大程度上帮助了变化的调整。

④ 变更的阶段化是一种必要的技术。每个产品都应该有数字版本号每个版本都应该有自己的日程表和冻结日期,在此之后的变更属于下一个版本的范畴。

Part 4 为变更计划组织架构

当系统发生变化时,管理结构也需要进行调整。这意味着,只要管理人员和技术人才的天赋允许,老板必须对他们的能力培养给予极大的关注,使管理人员和技术人才具有互换性。

这其中的障碍是社会性的,人们必须同顽固的戒心做斗争。首先,管理人员自己常常认为高级人员太“有价值”,而舍不得让他们从事实际的编程工作;其次,管理人员拥有更高的威信。

管理人员需要参与技术课程,高级技术人才需要进行管理培训。项目目标、进展、 管理问题必须在高级人员整体中得到共享。

只要能力允许,高层人员必须时刻做好技术和情感上的准备,以管理团队或者亲自参与开发工作。

组建外科手术队伍式的软件开发团队,这其结果是当高级人才编程和开发时,不会感到自降身份。

上述组织架构的设计是为了最小化成员间的接口。同样的,它使系统在最大程度上易于修改。当组织构架必须变化时,为整个“外科手术队伍”重新安排不同的软件开发任务,会变得相对容易一些。这的确是一个长期有效的灵活组织构架解决方案。

Part 5 前进两步,后退一步

在程序发布给顾客使用之后,它不会停止变化。发布后的变更被称为“程序维护”。

计算机系统的硬件维护包括了三项活动—替换损坏的器件、清洁和润滑、修改设计上的缺陷。(大多数情况下—但不是全部—变更修复的是实现上、 而不是结构上的一些缺陷。对于用户而言,这常常是不可见的。)

软件维护主要包含对设计缺陷的修复。和硬件维护相比,这些软件变更包含了更多的新增功能,它通常是用户能察觉的。

对于一个广泛使用的程序,其维护总成本通常是开发成本的40%或更多。令人吃惊的是,该成本受用户数目的严重影响。用户越多,所发现的错误也越多。

麻省理工学院核科学实验室的 Betty Campbell 指出特定版本的软件发布生命期中一个有趣的循环

起初,上一个版本中被发现和修复的 bug,在新的版本中仍会出现。新版本中的新功能会产生新的 bug。

解决了这些问题之后,程序会正常运行几个月。接着,错误率会重新攀升。Campbell 认为这是因为用户的使用到达了新的熟练水平,他们开始运用新的功能。这种高强度的考验查出了新功能中很多不易察觉的问题。

 

    程序维护中的一个基本问题是—缺陷修复总会以(20-50)%的几率引入新的bug。所以整个过程是前进两步,后退一步。

为什么缺陷不能更彻底地被修复?

首先,看上去很轻微的错误,似乎仅仅是局部操作上的失败,实际上却是系统级别的问题,通常这不是很明显。修复局部问题的工作量很清晰,并且往往不大。但是,更大范围的修复工作常常会被忽视,除非软件结构很简单,或者文档书写得非常详细。其次,维护人员常常不是编写代码的开发人员,而是一些初级程序员或者新手。

作为引入新 bug 的一个后果,程序每条语句的维护需要的系统测试比其他编程要多。理论上,在每次修复之后,必须重新运行先前所有的测试用例,从而确保系统不会以更隐蔽的方式被破坏。实际情况中,回归测试必须接近上述理想状况,所以它的成本非常高。

显然,使用能消除、至少是能指明副作用的程序设计方法,会在维护成本上有很大的回报。同样,设计实现的人员越少、接口越少,产生的错误也就越少。

Part 6 前进一步,后退一步

Lehman 和 Belady 研究了大型操作系统的一系列发布版本的历史。他们发现模块数量随版本号的增加呈线性增长,但是受到影响的模块以版本号指数的级别增长。所有修改都倾向于破坏系统的架构,增加了系统的混乱程度。用在修复原有设计上瑕疵的工作量越来越少,而早期维护活动本身的漏洞所引起修复工作越来越多。随着时间的推移,系统变得越来越无序,修复工作迟早会失去根基。每一步前进都伴随着一步后退。尽管理论上系统一直可用,但实际上,整个系统已经面目全非,无法再成为下一步进展的基础。而且,机器在变化,配置在变化,用户的需求在变化,所以现实系统不可能永远可用。崭新的、基于原有系统的重新设计是完全必要的

    系统软件开发是减少混乱度(减少熵)的过程,所以它本身是处于亚稳态的。软件维护是提高混乱度(增加熵)的过程,即使是最熟练的软件维护工作,也只是放缓了系统退化到非稳态的进程。

作者总结

11.1 化学工程师已经认识到无法一步将实验室工作台上的反应过程移到工厂中,需要一个实验性工厂(pilot planet)来为提高产量和在缺乏保护的环境下运作提供宝贵经验。

11.2 对于编程产品而言,这样的中间步骤是同样必要的,但是软件工程师在着手发布产品之前,却并不会常规地进行试验性系统的现场测试。[现在,这已经成为了一项普遍的实践,beta 版本。它不同于有限功能的原型,alpha 版本,后者同样是我所倡导的实践。]

11.3 对于大多数项目,第一个开发的系统并不合用。它可能太慢、太大,而且难以使用,或者三者兼而有之。

11.4 系统的丢弃和重新设计可以一步完成,也可以一块块地实现。这是个必须完成的步骤。

11.5 将开发的第一个系统——丢弃原型——发布给用户,可以获得时间,但是它的代价高昂——对于用户,使用极度痛苦;对于重新开发的人员,分散了精力;对于产品,影响了声誉,即使最好的再设计也难以挽回名声。

11.6 因此,为舍弃而计划&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值