第五章第一节 可复用性的度量、形态和外部观察
本节探讨可复用软件的形态与特征,下一节学习“如何构造”。 java
Outline
- 什么是软件复用
- 可复用实现的级别
- 源代码级别的复用
- 模块级别的复用:类、抽象类、接口
- 库级别的复用:API、包
- 系统级别的复用:框架
- 对可复用性的外部观察
- 白盒框架和黑盒框架
Notes
## 什么是软件复用
- 软件复用是使用现有软件组件实施或更新软件系统的过程。
- 软件复用的两个观点:
- 面向复用编程(programming for reuse):开发出可复用的软件
- 开发成本高于通常软件的成本:要有足够高的适应性
- 性能差些: 针对更普适场景,缺乏足够的针对性
- 基于复用编程(programming with reuse):利用已有的可复用软件搭建应用系统
- 可复用软件库,对其进行有效的管理
- 每每没法拿来就用,须要适配
- 为何须要复用:
- 复用下降成本和开发时间
- 复用的代码通过充分测试,可靠、稳定
- 产出标准化,在不一样应用中保持一致
- 软件复用的代价:
- 软件可复用的部分须要设计在以下的标准上:明确的定义、开放的方法、简洁的交互规范、可理解的文档,并着眼于将来。
- 不只program for reuse代价高,program with reuse代价也高

- 代码复用的类型:
- 白盒复用:源代码可见,可修改和扩展
- 含义:复制已有代码到正在开发的系统,进行修改
- 优势:可订制化程度高
- 缺点:对其修改增长了软件的复杂度,且须要对其内部充分的了解
- 黑盒服用:源代码不可见,不能修改
- 含义:只能经过过API接口来使用,没法修改代码
- 优势:清晰、简单
- 缺点:适用性差
- 高复用性的软件应具备以下特性:
- 小、简单
- 与标准兼容
- 灵活可变
- 可扩展
- 泛型、参数化
- 模块化
- 变化的局部性
- 稳定
- 丰富的文档和帮助
- 栗子:JDK中可复用的库和API

## 可复用实现的级别
【源代码级别的复用】git
相关研究1:如何从互联网上快速找到须要的代码片断? 程序员
反向研究:如何从源代码中检测出克隆代码(clone code)?github
咱们能够在如github和searchcode的网站上搜索代码,实现复用。编程
【模块级别的复用:类、抽象类、接口】设计模式
- 复用类:
- 源码并不是是必要的,可能只须要类文件或jar
- 只须要将这个类加入到类路径
- 可使用工具javap得到一个类的public方法
- 使用复用类的注意事项:
- 文档十分重要
- 压缩会有助于复用
- 管理更少的代码
- 版本兼容性
- 须要和类相关的包
- 复用类的方法:继承和委派
- 继承(Inheritance):
- 类扩展了现有类的属性/行为;
- 另外,他们可能会
Override
现有的行为;
- 一般须要在实施以前设计继承层次结构;
- 委派(Delegation):
- 根本没有父子关系的类中使用继承是不合理的,能够用委派的方式来代替。
- 委托是简单的将一个对象链接到另外一个对象上,使另外一个对象得到这个对象方法的子集(一个实体将某个事物传递给另外一个实体)。
- 明确的委托:明确将须要传的对象传到目标对象上
- 含蓄的委托:委托能够被描述为一种共享代码数据的低级别机制
- 委派的类型:
- Use(A uses B)
- Composition/aggregation (A owns B)
- Association (A has B)
【库级别的复用:API/包】框架
- 方法:Libaray、framework
- library:
- 库定义:一组提供可重用功能的类和方法(API)
- 开发者构造可运行软件实体,其中涉及到对可复用库的调用
- Java中有不少的库能够复用,例如Guava:Google的Java核心库;Apache Commons等
- framework:
- 框架定义:一组具体类、抽象类、及其之间的链接关系
- 做为主程序加以执行,执行过程当中调用开发者所写的程序
- 开发者根据 framework的规约,填充本身的代码进去,造成完整系统
【系统级别的复用:框架】ide

将framework看做是更大规模的API复用,除了提供可复用的API,还将这 些模块之间的关系都肯定下来,造成了总体应用的领域复用。开发者的任务就是增长新代码、对抽象类进行具体化。展开来讲就是如下几点:模块化
- 一般经过选择性覆盖来扩展框架; 或者程序员能够添加专门的用户代码来提供特定的功能—定义继承了抽象类祖先操做的具体类
- 设计模式(Hook方法),它被应用程序覆盖以扩展框架。 Hook方法系统地将应用程序域的接口和行为与应用程序在特定上下文中所需的变体解耦。
- 控制反转,由第三方的容器来控制对象之间的依赖关系,而非传统实现中由代码直接操控。由第三方的容器来控制对象之间的依赖关系,而非传统实现中由代码直接操控。
- 不可修改的框架代码:在接受用户实现的扩展时,框架代码不该该被修改。 换句话说,用户能够扩展框架,但不该修改其代码。
## 对可复用性的外部观察
- Type Variation 类型可变
- 可以复用的部分应该类型参数化,以适应不一样的数据类型
- 复用的部分应该通常化
- 适应不一样的类型,且知足LSP
- Implementation Variation 实现可变
- ADT 有多种不一样的实现,提供不一样的representations 和abstract function ,但具备一样的specification (pre-condition, post-condition, invariants) ,从而能够适应不一样的应用场景
- Routine Grouping 功能分组
- 提供完备的细粒度操做,保证功能的完整性,不一样场景下复用不一样的操做( 及其组合)
- Representation Independence 表示独立
- Factoring Out Common Behaviors 共性抽取
## 白盒框架和黑盒框架
框架也可分为白盒框架和黑盒框架两类。 工具
- 白盒框架:
- 经过继承和动态绑定实现可扩展性。
- 经过继承框架基类并重写预约义的hook方法来扩展示有功能。
- 一般使用模板方法模式等设计模式来覆盖hook方法。
- 黑盒框架:
- 经过为可插入框架的组件定义接口来实现可扩展性。
- 经过定义符合特定接口的组件来复用现有功能。
- 这些组件经过委派(Delegation)与框架集成。