标题：软件复用
提出背景
软件复用是一种计算机软件工程方法和理论。60年代的“软件危机”使程序设计人员明白难于维护的软件成本是极其高昂的，当软件的规模不断扩大时，这种软件的综合成本可以说是没有人能负担的，并且即使投入了高昂的资金也难以得到可靠的产品，而软件重用的思想是解决这一问题的根本方法。
主要思想
软件复用的主要思想是，将软件看成是由不同功能部分的“组件”所组成的有机体，每一个组件在设计编写时可以被设计成完成同类工作的通用工具，这样，如果完成各种工作的组件被建立起来以后，编写一特定软件的工作就变成了将各种不同组件组织连接体来的简单问题，这对于软件产品的最终质量和维护工作都有本质性的改变。
软件复用的特点和现状
软件复用就是将已有的软件成分用于构造新的软件系统。可以被复用的软件成分一般称作可复用构件，无论对可复用构件原封不动地使用还是作适当的修改后再使用，只要是用来构造新软件，则都可称作复用。软件复用不仅仅是对程序的复用，它还包括对软件生产过程中任何活动所产生的制成品的复用，如项目计划、可行性报告、需求定义、分析模型、设计模型、详细说明、源程序、测试用例等等。如果是在一个系统中多次使用一个相同的软件成分，则不称作复用，而称作共享；对一个软件进行修改，使它运行于新的软硬件平台也不称作复用，而称作软件移值。
复用级别
目前及近期的未来最有可能产生显著效益的复用是对软件生命周期中一些主要开发阶段的软件制品的复用，按抽象程度的高低，可以划分为如下的复用级别：（1）代码的复用包括目标代码和源代码的复用。其中目标代码的复用级别最低，历史也最久，当前大部分编程语言的运行支持系统都提供了连接（Link）、绑定(Binding)等功能来支持这种复用。源代码的复用级别略高于目标代码的复用，程序员在编程时把一些想复用的代码段复制到自己的程序中，但这样往往会产生一些新旧代码不匹配的错误。想大规模的实现源程序的复用只有依靠含有大量可复用构件的构件库。如”对象链接及嵌入”（OLE）技术，既支持在源程序级定义构件并用以构造新的系统，又使这些构件在目标代码的级别上仍然是一些独立的可复用构件，能够在运行时被灵活的得新组合为各种不同的应用。（2）设计的复用设计结果比源程序的抽象级别更高，因此它的复用受实现环境的影响较少，从而使可复用构件被复用的机会更多，并且所需的修改更少。这种复用有三种途径，第一种途径是从现有系统的设计结果中提取一些可复用的设计构件，并把这些构件应用于新系统的设计；第二种途径是把一个现有系统的全部设计文档在新的软硬件平台上重新实现，也就是把一个设计运用于多个具体的实现；第三种途径是独立于任何具体的应用，有计划地开发一些可复用的设计构件。（3）分析的复用这是比设计结果更高级别的复用，可复用的分析构件是针对问题域的某些事物或某些问题的抽象程度更高的解法，受设计技术及实现条件的影响很少，所以可复用的机会更大。复用的途径也有三种，即从现有系统的分析结果中提取可复用构件用于新系统的分析；用一份完整的分析文档作输入产生针对不同软硬件平台和其它实现条件的多项设计；独立于具体应用，专门开发一些可复用的分析构件。（4）测试信息的复用主要包括测试用例的复用和测试过程信息的复用。前者是把一个软件的测试用例在新的软件测试中使用，或者在软件作出修改时在新的一轮测试中使用。后者是在测试过程中通过软件工具自动地记录测试的过程信息，包括测试员的每一个操作、输入参数、测试用例及运行环境等一切信息。这种复用的级别，不便和分析、设计、编程的复用级别作准确的比较，因为被复用的不是同一事物的不同抽象层次，而是另一种信息，但从这些信息的形态看，大体处于与程序代码相当的级别。 
由于软件生产过程主要是正向过程，即大部分软件的生产过程是使软件产品从抽象级别较高的形态向抽象级别较低的形态演化，所以较高级别的复用容易带动较低级别的复用，因而复用的级别越高，可得到的回报也越大，因此分析结果和设计结果在目前很受重视。用户可购买生产商的分析件和设计件，自己设计或编程，掌握系统的剪裁、扩充、维护、演化等活动。
软件复用的根本困难
软件复用各方面的困难，无论是技术问题还是非技术问题，都影响着软件复用的广泛实行。（1）技术因素构件与应用系统之间的差异。一些开发者开发的构件，要做到在被另一些人开发的系统中使用时正好合适，从内容到对外接口都恰好相符，或者作很少的修改，这不是一件简单的事；构件要达到一定的数量，才能支持有效的复用，而大量构件的获得需要有很高的投入和长期的积累；发现合用构件的困难，当构件达到较大的数量时，使用者要从中找到一个自己想要的构件，并断定它确实是自己需要的，不是一件轻而易举的事；基于复用的软件开发方法和软件过程是一个新的研究实践领域，需要一些新的理论、技术及支持环境，目前这方面的研究成果和实践经验都不够充分。（2）人的因素软件开发是一种创造性工作，长期从事这个行业的人们形成了一种职业习惯：喜欢自己创造而不喜欢使用别人的东西，特别是当要对别人开发的软件作一些修改再使用时，他们常常喜欢自己另写一个。（3）管理因素在软件生产的管理中，从以往沿习了一些与复用的目标很不协调的制度与政策，如计算工作量时，对复用的部分打很大的折扣，甚至不算工作量；另外，不是在项目开始时自觉地向着造就可复用构件的方向努力，而是在它完成之后，看看是否能从中找到一些可复用构件。这些弊端妨碍了复用水平的提高和复用规模的扩大，甚至会挫伤致力于复用的人员的积极性。（4）教育因素在软件科学技术的教育与培训中，缺乏关于软件复用的内容，很少有这方面的专门教材及课程，即使在其它教材及课程中提到软件复用，其篇幅及内容也相当薄弱。（5）法律因素在法律上还存在一些问题，例如，一个可复用构件在某个应用系统中出现了错误，而构件的开发者和应用系统的开发者不是一个厂商，那么责任应该由谁负？此外，在版权、政府政策等方面也存在一些悬而未决的问题。精神产品另外，软件产品是一种精神产品，它的产生几乎完全是人脑思维的结果，它的价值，也几乎完全在于其中所凝结的思想；它的物质载体的制造过程与价值含量都是微不足道的。物质产品的生产受到人类制造能力的限制，现有的一切物质产品的复杂性都没有超过这种限度，软件却没有这种限制，只要人的大脑能想到的问题，都可能要求软件去解决，人脑所能思考的问题的复杂性，远远超出了人类能制造的物质产品的复杂性，因而使软件的复用更为困难。
OO方法对软件复用的支持
支持软件复用是人们对面向对象方法寄托的主要希望之一，也是这种方法受到广泛重视的主要原因之一。面向对象方法之所以特别有利于软件复用，是由于它的主要概念及原则与软件复用的要求十分吻合。
面向对象方法从面向对象的编程发展到面向对象的分析与设计，使这种方法支持软件复用的固有特征能够从软件生命周期的前期阶段开始发挥作用，从而使OO方法对软件复用的支持达到了较高的级别。与其它软件工程方法相比，面向对象方法的一个重要优点是，它可以在整个软件生命周期达到概念、原则、术语及表示法的高度一致。这种一致性使得各个系统成分尽管在不同的开发与演化阶段有不同的形态，但可具有贯穿整个软件生命周期的良好映射。这一优点使OO方法不但能在各个级别支持软件复用，而且能对各个级别的复用形成统一的、高效的支持，达到良好的全局效果。做到这一点的必要条件是，从面向对象软件开发的前期阶段---OOA就把支持软件复用作为一个重点问题来考虑。运用OOA方法所定义的对象类具有适合作为可复用构件的许多特征，OOA结果对问题域的良好映射，使同类系统的开发者容易从问题出发，在已有的OOA结果中发现不同粒度的可复用构件。
（1）OOA模型
OOA方法建立的系统模型分为基本模型（类图）和补充模型（主题图与交互图），强调在OOA基本模型中只表示最重要的系统建模信息，较为细节的信息则在详细说明中结出。这种表示策略使OOA基本模型体现了更高的抽象，更容易成为一个可复用的系统构架。当这个构架在不同的应用系统中复用时，在很多情况下可通过不同的详细说明体现系统之间的差异，因此对系统构件的改动较少。
(2）OOA与OOD的分工
OOA只注重与问题域及系统责任有关的信息，OOD考虑与实现条件有关的因素。这种分工使OOA模型独立于具体的实现条件，从而使分析结果可以在问题域及系统责任相同而实现条件互异的多个系统中复用，并为从同一领域的多个系统的分析模型提炼领域模型创造了有利条件。
（3） 对象的表示
所有的对象都用类作为其抽象描述。对象的一却信息，包括对象的属性、行为及其对外关系等等都是通过对象类来表示的。类作为一种可复用构件，在运用于不同系统时，不会出现因该类对象实例不同而使系统模型有所不同的情况。
（4） 一般-特殊结构
引入对一般-特殊结构中多态性的表示法，从而增强了类的可复用性。通过对多态性的表示，使一个类可以在需求相似而未必完全相同的系统中被复用。 
（5）整体-部分结构
把部分类作为可复用构件在整个类中使用，这种策略的原理与在特殊类中使用一般类是一致的，但在某些情况下，对问题域的映射比通过继承实现复用显得更为自然。另外还可通过整体-部分结构支持领域复用的策略---从整体对象中分离出一组可在领域范围内复用的属性与服务，定义为部分对象，使之成为领域复用构件。
（6）实例连接
建议用简单的二元关系表示各种复杂关系和多元关系。这一策略使构成系统的基本成分（对象类）以及它们之间的关系在表示形式和实现技术上都是规范和一致的这种规范性和一致性对于可复用构件的组织、管理和使用，都是很有益的。
（7）类描述模板
作为OOA详细说明主要成分的类描述模板，对于对象之间关系的描述注意到使用者与被使用者的区别，仅在使用者一端给出类之间关系的描述信息。这说明可复用构件之间的依赖关系不是对等的。因此，在继承、聚合、实例连接及消息连接等关系的使用者一端描述这些关系，有利于这些关系信息和由它们指出的被依赖成份的同时复用。在被用者一端不描述这些关系，则避免了因复用场合的不同所引起的修改。
（8）使用CASE
由于使用CASE是对用户需求的一种规范化描述，因此它比普通形式的需求文档具有更强的可复用性。每个使用case 是对一个活动者使用系统的一项功能时的交互活动所进行描述，它具有完整性和一定的独立性，因此很适于作为可复用构件。
复用技术对OO方法的支持
面向对象的软件开发和软件复用之间的关系是相辅相成的。一方面，OO方法的基本概念、原则与技术提供了实现软件复用的有利条件；另一方面，软件复用技术也对面向对象的软件开发提供了有力的支持。
（1）类库
在面向对象的软件开发中，类库是实现对象类复用的基本条件。人们已经开发了许多基于各种OOPL的编程类库，有力地支持了源程序级的软件复用，但要在更高的级别上实现软件复用，仅有编程类库是不够的。实现OOA结果和OOD结果的复用，必须有分析类库和设计类库的支持。为了更好地支持多个级别的软件复用，可以在OOA类库、OOD类库和OOP类库之间建立各个类在不同开发阶段的对应与演化关系。即建立一种线索，表明每个OOA的类对应着哪个（或哪些）OOD类，以及每个OOD类对应着各种OO编程语言类库中的哪个OOP类。
（2） 构件库
类库可以看作一种特殊的可复用构件库，它为在面向对象的软件开发中实现软件复用提供了一种基本的支持。但类库只能存储和管理以类为单位的可复用构件，不能保存其它形式的构件；但是它可以更多地保持类构件之间的结构与连接关系。构件库中的可复用构件，既可以是类，也可以是其它系统单位；其组织方式，可以不考虑对象类特有的各种关系，只按一般的构件描述、分类及检索方法进行组织。在面向对象的软件开发中，可以提炼比对象类粒度更大的可复用构件，例如把某些结构或某些主题作为可复用构件；也可以提炼其它形式的构件，例如use case 或交互图。这些构件库中，构件的形式及内容比类库更丰富，可为面向对象的软件开发担供更强的支持。
（3）构架库
如果在某个应用领域中已经运用OOA技术建立过一个或几个系统的OOA模型，则每个OOA模型都应该保存起来，为该领域新系统的开发提供参考。当一个领域已有多个OOA模型时，可以通过进一步抽象而产生一个可复用的软件构架。形成这种可复用软件构架的更正规的途径是开展领域分析。通过正规的领域分析获得的软件构架将更准确地反映一个领域中各个应用系统的共性，具有更强的可复用价值。
（4）工具
有效的实行软件复用需要有一些支持复用的软件工具，包括类库或构件/构架库的管理、维护与浏览工具，构件提取及描述工具，以及构件检索工具等等。以复用支持为背景的OOA工具和OOD工具在设计上也有相应的要求，工具对OOA/OOD过程的支持功能应包括：从类库或构件/构架库中寻找可复用构件；对构件进行修改，并加入当前的系统模型；把当前系统开发中新定义的类（或其它构件）提交到类库（或构件库）。
（5）OOA过程
在复用技术支持下的OOA过程，可以按两种策略进行组织。第一种策略是，基本保持某种OOA方法所建议的OOA过程原貌，在此基础上对其中的各个活动引入复用技术的支持；另一种策略是重新组织OOA过程。
第一种策略是在原有的OOA过程基础上增加复用技术的支持，应补充说明的一点是，复用技术支持下的OOA过程应增加一个提交新构件的活动。即在一个具体应用系统的开发中，如果定义了一些有希望被其它系统复用的构件，则应该把它提交到可复用构件库中。第二种策略的前提是：在对一个系统进行面向对象的分析之前，已经用面向对象方法对该系统所属的领域进行过领域分析，得到了一个用面向对象方法表示的领域构架和一批类构件，并且具有构件/构架库、类库及相应工具的支持。在这种条件下，重新考虑OOA过程中各个活动的内容及活动之间的关系，力求以组装的方式产生OOA模型，将使OOA过程更为合理，并达到更高的开发效率。