一、软件复用
(一)可复用软件概念
软件复用是指在两次或多次不同的软件开发过程中重复使用相同或相近的软件或软件模块的过程。
该软件可以是已经存在的软件或是专门的可复用软件,称为构建。
(二)复用级别
1.代码的复用
包括目标代码和源代码的复用。其中目标代码的复用级别最低,历史也最久,当前大部分编程语言的运行支持系统都提供了连接(Link)、绑定(Binding)等功能来支持这种复用。源代码的复用级别略高于目标代码的复用,程序员在编程时把一些想复用的代码段复制到自己的程序中,但这样往往会产生一些新旧代码不匹配的错误。想大规模的实现源程序的复用只有依靠含有大量可复用构件的构件库。
2.设计的复用
设计结果比源程序的抽象级别更高,因此它的复用受实现环境的影响较少,从而使可复用构件被复用的机会更多,并且所需的修改更少。
这种复用有三种途径:
第一种途径是从现有系统的设计结果中提取一些可复用的设计构件,并把这些构件应用于新系统的设计。
第二种途径是把一个现有系统的全部设计文档在新的软硬件平台上重新实现,也就是把一个设计运用于多个具体的实现。
第三种途径是独立于任何具体的应用,有计划地开发一些可复用的设计构件。
3.分析的复用
这是比设计结果更高级别的复用,可复用的分析构件是针对问题域的某些事物或某些问题的抽象程度更高的解法,受设计技术及实现条件的影响很少,所以可复用的机会更大。
复用的三种途径:
①从现有系统的分析结果中提取可复用构件用于新系统的分析。
②用一份完整的分析文档作输入产生针对不同软硬件平台和其它实现条件的多项设计。
③独立于具体应用,专门开发一些可复用的分析构件。
4.测试信息的复用
主要包括测试用例的复用和测试过程信息的复用。前者是把一个软件的测试用例在新的软件测试中使用,或者在软件作出修改时在新的一轮测试中 使用。后者是在测试过程中通过软件工具自动地记录测试的过程信息,包括测试员的每一个操作、输入参数、测试用例及运行环境等一切信息。这种复用的级别,不便和分析、设计、编程的复用级别作准确的比较,因为被复用的不是同一事物的不同抽象层次,而是另一种信息,但从这些信息的形态看,大体处于与程序代码相当的级别。
二、从类、API、框架三个层面分析
(一)类
可复用的类主要包括:委托和组合
1.委托
委派/委托:一个对象请求另一个对象的功能,是复用的一种常见形式。
委托可以被描述为在实体之间共享代码和数据的低级机制
委托依赖于动态绑定,因为它要求给定的方法调用可以在运行时调用不同的代码段。
2.组合继承原则
类应该通过它们的组合实现多态行为和代码重用(通过包含实现所需功能的其他类的实例),而不是从基类或父类继承。
组合原则:
使用接口定义系统必须对外展示的不同侧面的行为,例如,一只鸟可以叫也可以飞,那么可以定义两个接口,quackable和flyable。
接口之间通过extends实现行为的扩展(接口组合)。然后可以定义一个接口birdable同时继承了上述两个接口,这样这个新的接口就有了上述两个接口的全部功能。
类implements 组合接口,从而规避了复杂的继承关系。接下来,我们定义的“鸟类”就可以实现birdable,使得活动顶层接口的功能(在构造实例的过程中,同时要delegation顶层功能的接口)
3.Liskov替换原则(LSP)
里氏替换原则的主要作用就是规范继承时子类的一些书写规则。其主要目的就是保持父类方法不被覆盖。
含义:
- 子类必须完全实现父类的方法
- 子类可以有自己的个性
- 覆盖或实现父类的方法时输入参数可以被放大
- 覆盖或实现父类的方法时输出结果可以被缩小
(二)API
API是程序员最重要的资产和“荣耀”,吸引外部用户,提高声誉。
建议:始终以开发API的标准面对任何开发任务;面向“复用”编程而不是面向“应用”编程。
难度:要有足够良好的设计,一旦发布就无法再自由改变。编写一个API需要考虑以下方面:
①API应该做一件事,且做得很好
②API应该尽可能小,但不能太小③Implementation不应该影响API
④记录文档很重要
⑤考虑性能后果
⑥API必须与平台和平共存
类的设计:尽量减少可变性,遵循LSP原则 方法的设计:不要让客户做任何模块可以做的事情,及时报错
(三)框架
框架:一组具体类、抽象类、及其之间的连接关系
开发者根据 framework的规约,填充自己的代码进去,形成完整系统。通常通过选择性覆盖来扩展框架;或者程序员可以添加专门的用户代码来提供特定的功能—即定义继承了抽象类祖先操作的具体类 Hook方法,它被应用程序覆盖以扩展框架。Hook方法系统地将应用程序域的接口和行为与应用程序在特定上下文中所需的变体解耦。 控制反转:与库或标准用户应用程序不同,控制流不是由调用者决定的,而是由框架决定的。不可修改的框架代码:在接受用户实现的扩展时,框架代码不应该被修改。换句话说,用户可以扩展框架,但不应修改其代码。
框架分为白盒框架和黑盒框架。
1. 白盒框架:
白盒复用:源代码可见,可修改和扩展,复制已有代码当正在开发的系统,进行修改,通过子类化和重写方法进行扩展(使用继承)
通过子类化和重写方法进行扩展(使用继承)。
通用设计模式:模板方法。
子类具有主要方法但对框架进行控制。
优点:可定制化程度高
缺点: 对其修改增加了软件的复杂度,且需要对其内部充分的了解
2.黑盒框架:
黑盒复用:源代码不可见,不能修改,只能通过API接口来使用,无法修改代码,通过实现插件接口进行扩展(使用组合/委派)
通过实现插件接口进行扩展(使用组合/委派)。
常用设计模式:Strategy, Observer 。
插件加载机制加载插件并对框架进行控制。
优点:简单清晰
缺点:适应性差