一、可复用软件
1、可复用软件概念介绍
软件复用是指在两次或多次不同的软件开发过程中重复使用相同或相近的软件或软件模块的过程。该软件可以是已经存在的软件或是专门的可复用软件,称为(软)构建。
2、软件的复用可以从两方面展开
(1)面向复用的编程:开发出可复用的软件
(2)基于复用编程:利用已有的可复用软件搭建应用系统
3、复用级别主要包括以下内容
(1)代码的复用
包括目标代码和源代码的复用。其中目标代码的复用级别最低,历史也最久,当前大部分编程语言的运行支持系统都提供了连接(Link)、绑定(Binding)等功能来支持这种复用。源代码的复用级别略高于目标代码的复用,程序员在编程时把一些想复用的代码段复制到自己的程序中,但这样往往会产生一些新旧代码不匹配的错误。想大规模的实现源程序的复用只有依靠含有大量可复用构件的构件库。如”对象链接及嵌入”(OLE)技术,既支持在源程序级定义构件并用以构造新的系统,又使这些构件在目标代码的级别上仍然是一些独立的可复用构件,能够在运行时被灵活的得新组合为各种不同的应用。
(2)设计的复用
设计结果比源程序的抽象级别更高,因此它的复用受实现环境的影响较少,从而使可复用构件被复用的机会更多,并且所需的修改更少。这种复用有三种途径,第一种途径是从现有系统的设计结果中提取一些可复用的设计构件,并把这些构件应用于新系统的设计;第二种途径是把一个现有系统的全部设计文档在新的软硬件平台上重新实现,也就是把一个设计运用于多个具体的实现;第三种途径是独立于任何具体的应用,有计划地开发一些可复用的设计构件。
(3)分析的复用
这是比设计结果更高级别的复用,可复用的分析构件是针对问题域的某些事物或某些问题的抽象程度更高的解法,受设计技术及实现条件的影响很少,所以可复用的机会更大。复用的途径也有三种,即从现有系统的分析结果中提取可复用构件用于新系统的分析;用一份完整的分析文档作输入产生针对不同软硬件平台和其它实现条件的多项设计;独立于具体应用,专门开发一些可复用的分析构件。
(4)测试信息的复用
主要包括测试用例的复用和测试过程信息的复用。前者是把一个软件的测试用例在新的软件测试中使用,或者在软件作出修改时在新的一轮测试中使用。后者是在测试过程中通过软件工具自动地记录测试的过程信息,包括测试员的每一个操作、输入参数、测试用例及运行环境等一切信息。这种复用的级别,不便和分析、设计、编程的复用级别作准确的比较,因为被复用的不是同一事物的不同抽象层次,而是另一种信息,但从这些信息的形态看,大体处于与程序代码相当的级别。
由于软件生产过程主要是正向过程,即大部分软件的生产过程是使软件产品从抽象级别较高的形态向抽象级别较低的形态演化,所以较高级别的复用容易带动较低级别的复用,因而复用的级别越高,可得到的回报也越大,因此分析结果和设计结果在目前很受重视。用户可购买生产商的分析件和设计件,自己设计或编程,掌握系统的剪裁、扩充、维护、演化等活动。
二、从类、API、框架三个层面分析
1、首先从类方面
可复用的类主要包括:委托和组合
(1)委托(Delegation)
- 委派/委托:一个对象请求另一个对象的功能,是复用的一种常见形式。
委托可以被描述为在实体之间共享代码和数据的低级机制。
委托依赖于动态绑定,因为它要求给定的方法调用可以在运行时调用不同的代码段。
- 委托和继承的比较:
继承:通过新操作扩展基类或覆盖操作。
委托:把基类拿过来作为新的类的元素,可以用基类以实现的功能扩展新类的功能
- 委托可以替代继承的情况:如果子类只需要复用父类中的一小部分方法,可以不需要使用继承,而是通过委派机制来实现
(2)组合继承原则
类应该通过它们的组合实现多态行为和代码重用(通过包含实现所需功能的其他类的实例),而不是从基类或父类继承。
组合原则:
使用接口定义系统必须对外展示的不同侧面的行为,例如,一只鸟可以叫也可以飞,那么可以定义两个接口,quackable和flyable。
接口之间通过extends实现行为的扩展(接口组合)。然后可以定义一个接口birdable同时继承了上述两个接口,这样这个新的接口就有了上述两个接口的全部功能。
类implements 组合接口,从而规避了复杂的继承关系。接下来,我们定义的“鸟类”就可以实现birdable,使得活动顶层接口的功能(在构造实例的过程中,同时要delegation顶层功能的接口)
2、可复用的API和框架:
(1)之所以库和框架被称为系统层面的复用,是因为它们不仅定义了一个可复用的接口/类,而是将某个完整系统中的所有可复用的接口/类都实现出来,并且定义了这些类之间的交互关系、调用关系,从而形成了系统整体的“架构”。
编写一个API需要考虑以下方面:
API应该做一件事,且做得很好
API应该尽可能小,但不能太小
Implementation不应该影响API
记录文档很重要
考虑性能后果
API必须与平台和平共存
类的设计:尽量减少可变性,遵循LSP原则
方法的设计:不要让客户做任何模块可以做的事情,及时报错
(2)框架
框架:一组具体类、抽象类、及其之间的连接关系开发者根据 framework的规约,填充自己的代码进去,形成完整系统。通常通过选择性覆盖来扩展框架;或者程序员可以添加专门的用户代码来提供特定的功能——即定义继承了抽象类祖先操作的具体类 Hook方法,它被应用程序覆盖以扩展框架。Hook方法系统地将应用程序域的接口和行为与应用程序在特定上下文中所需的变体解耦。
**控制反转:**与库或标准用户应用程序不同,控制流不是由调用者决定的,而是由框架决定的。
**不可修改的框架代码:**在接受用户实现的扩展时,框架代码不应该被修改。换句话说,用户可以扩展框架,但不应修改其代码。
常见的框架类似于spring框架这种,spring框架代码不能修改但是拥有DI,IOC,方便用户创建对象,何时创建对象,交给系统来判断,用户只需要使用对象就行了。
类型也有两种:
白盒复用:源代码可见,可修改和扩展,复制已有代码当正在开发的系统,进行修改,通过子类化和重写方法进行扩展(使用继承)。
优点:可定制化程度高
缺点: 对其修改增加了软件的复杂度,且需要对其内部充分的了解
黑盒复用:源代码不可见,不能修改,只能通过API接口来使用,无法修改代码,通过实现插件接口进行扩展(使用组合/委派)。
优点:简单清晰
缺点:适应性差
三、学习心得
随着软件的发展,软件的规模与复杂度越来越高,随之而来的就是软件的设计开发与维护成本越来越高,人们在应对软件危机的过程中已经认识到很多时候人们需要与需求的变化作斗争,而复用是应对需求变化的有力武器。
用的发展变化复在面向过程的软件开发中,复用主要体现在函数这一级,人们将公用的功能写成函数,在不同项目中主要是靠复制粘贴的方式进行复用,随后发展为库函数,复用的方式有了一些改进,这其实也是构件的一个雏形。随着软件规模的扩大,人们引进了面向对象的思想,向对象技术面提供了一种.新的认知和表示世界的思想和方法。用对象来作为描写客观世界的基本单元,它包括封装在一起的对象属性和对象操作。面向对象技术是以对象为基础来构建系统的。通过把这些有关连的变量和函数封装在一个对象中,大大的简化了编程的复杂性,提高了程序可读性,并且提供了一种抽象,该抽象是可扩展性的关键。面向对象使得软件的开发与业务逻辑联系进一步加强,使得大规模设计与开发成为可能。在这个过程中,人们在面对类爆炸时,面对需求变化时总结与提炼出了基本的设计模式,设计模式很大程度上是防止人为地把软件设计搞复杂。软件的进一步发展,硬件就应运而生,硬件通常由规约和实现两部构成。
进行软件复用的意义:
1.提高生产率:软件复用最明显的好处在于提高生产率,从而减少开发代价。生产率的提高不仅体现在代码开发阶段。在分析、设计及测试阶段同样可以利用重用来节省开销。
2.减少维护代价:好的复用可以减少软件需要维护的部分。
3.提高互操作性:复用经过检验的构件,减少了可能的错误。基于复用技术生产的软件系统,大多使用相同的接口对外实现通信,因此系统将更为有效地实现与其他系统之间的互操作。
4.支持快速原型:可以快速构造出系统可操作的模型,以获得用户对系统功能的反馈。利用可复用构件可以快速有效地构造出应用程序的原型。
5.减少培训开销:使用一个可复用构件库时,可以减少所需的非正式的开销,因为其中的构件都是工程师所熟悉和精通的。
软件产品是人们的一种精神产品,它来于人们的思维大脑,因此其价值则是它所承载的思想精华。软件产品的价值是无法与实实在在的物
品去衡量和比较的,因为软件产品的特殊性就在于,人们可以发挥无限的形象力并赋予软件,其复杂性极大,软件复用自然也是如此。软件复用技术的关键在于领会并灵活运用软件复用思想。因此我们需要掌握其精髓,好好学习软件复用。