跳到主要内容

产品族与信息隐藏

什么是产品族?​

  • 提出者: David Parnas;
  • 主张: 设计人员应对产品的后期扩展和后续版本进行预测, 定义它们在功能或平台上的差异, 从而搭建一棵相关产品的家族树;
  • 产品族举例: 功能修改、移植到其他平台、第二代产品、内部版本、基产品;
  • 目标: 让模块重用最大化, 并让后续中间版本以最低限度的回溯代价生长;
  • 与传统"抛弃原型"的关系: 相同的策略不但可以包括发布产品, 还可以包括以增量开发策略创建的后续中间版本;

产品族设计的关键技巧是什么?​

  • 技巧: 把那些变化可能性较小的设计决策放置在树的根部;
  • 理由: 树根的决定被后续所有分支继承, 越靠近根部改动代价越大;
  • 配套: 定义功能或平台上的差异, 使模块的重用最大化;

信息隐藏和抽象数据类型、面向对象是什么关系?​

  • 第一步(Parnas): 模块定义为拥有自身数据模型和自身操作集的软件实体, 数据只能通过它自己的操作访问;
  • 第二步(多位思想家): 把 Parnas 模块提升为抽象数据类型, 从中可以派生出很多对象; 抽象数据类型提供了统一指明模块接口的方式和容易保证实施的类型规范化访问方法;
  • 第三步(面向对象): 引入继承, 即类默认获得类继承层次中祖先的属性;
  • 起源说明: 对象的思想首先由 Hoare 和 Dijkstra 提出, 第一个和最有影响力的案例是 Dahl 和 Nygaard 发明的 Simula-67;

面向对象的最大收益来自哪一步?​

  • 作者判断: 最大收获实际上来自第一步--模块隐藏, 以及预先建成的、为重用而设计和测试的模块或类库;
  • 不是继承: 很多人希望大规模重用, 但不付出构建产品级质量(通用、健壮、经过测试和文档化)模块所需要的初始代价, 这种期望是徒劳的;
  • 重要提醒: 上述模块不仅仅是程序, 某种意义上就是第 1 章讨论过的编程产品;
  • 应用节奏(Coggins): 面向对象不会加快首次或第二次开发, 产品族中第五个项目的开发才会异乎寻常地迅速;
  • 缓慢原因: 前期投入大(主要是培训程序员用很新的方法思考, 并把函数打造成通用类), 收益在后续开发、扩展和维护活动中才体现;
  • 另一原因(Parnas): 人们被告知 O-O 是一种特殊工具, 而不是一种设计方法; 没有教设计, 语言作用就很小;

重用的前提是什么?​

  • 判据(Van Snyder): 障碍不在生产者一边, 而在消费者一边--若消费者觉得"寻找并验证现成构件"比"自行编写"更昂贵, 重复构件就会产生; 关键在于"觉得", 与重新开发的真正投入无关;
  • 数学软件为什么重用成功: 它晦涩难懂, 每行代码需要大量高智商输入; 且存在丰富的标准术语来描述每个构件的功能;
  • 结论: 重新开发成本高、查找成本低的领域, 重用自然发生;
  • 定量经验: 有经验的程序员私人开发库可提供约 30% 的重用代码; 公司级重用可提供约 70%, 但需要特殊开发库和管理支持;
  • 成本(Yourdon): 可重用构件的工作量约是"一次性"构件的两倍; 作者本人的估计是三倍;
  • 文档前提(Parnas): 重用同时需要良好的设计和文档, 没有好的文档就看不到能重用的构件;
  • 词汇问题: 类库成员可能超过 3000 个, 很多对象需要 10-20 个参数; 使用者必须学习其语法(外部接口)和语义(详细功能行为); 解决办法是出版复合产品的例子, 在上下文中学习, 而不是只发布零部件库;