简介
软件架构复用
在应用软件系统的开发过程中,通常包含以下几个关键阶段:需求分析、设计、编码、测试和维护。在这些阶段中,复用技术均可以得到有效应用。特别是,软件架构复用作为一种大粒度、高抽象级别的复用方式,为后续的编码、测试等工作中的复用技术应用奠定了坚实的基础。
软件架构复用不仅关注系统的整体组织和结构,还涉及系统中各部分的接口选择、特定行为的定义、较大子系统的构成以及架构风格的确定。通过在架构设计阶段引入复用技术,可以显著提升系统的可维护性和可扩展性,同时降低开发成本和缩短开发周期。架构复用的核心在于通过预先定义和验证的架构模式和组件,确保在后续开发阶段中能够高效、可靠地复用这些经过验证的架构元素,从而提高整个软件开发过程的效率和质量。
软件复用的维度
- 水平复用 强调的是在不同应用程序或系统之间的复用,通常涉及通用的、独立的组件。
- 垂直复用 强调的是在同一应用程序的不同层次之间的复用,通常涉及特定的、业务相关的组件。
软件复用的方式
1. “原封不动”复用
“原封不动”复用是指寻找可以直接使用的现存类,以提供所需的特性。这种情况是所需要的类已经存在。现在建立它的一个实例,用以提供所需的特性。这个实例可以直接为应用软件利用,或者它可以用来做另一个类的实现部分。通过复用一个现存类,可以获得不加修改就能工作的已测试代码。
2. 进化性复用
进化性复用是指在找不到完全符合要求特性的类时,如果存在具有类似功能的类,可以通过继承来实现系统的功能需求。如果新类将要成为一个现存类的子类,它应当继承这个现存类的所有特性。然后,新类可以对需要追加的数据及必需的功能进行补充定义,还可以将几个现存类的特性混合起来开发出新的类。每个现存类是某些概念的模型,混合起来则产生了一个为特定待开发软件所用的具有多重概念的类。有时一个现存的类可能会提供某些新类中需要的特性和某些新类中不需要的特性。因此,可以先建立一个新的更抽象的类,使之成为要设计的类的父类,然后修改现存类以继承新的父类。
3. “废弃性”开发
“废弃性”开发是指在不使用任何复用的情况下开发一个新类。任何一个类,只要其开发不涉及现存类,就可以被视为一个新类的开始。因此,将建立两种类:一种是抽象类,它概括了将要表达的概念;另一种是具体类,它实现这个概念。虽然在开发新类时不需要使用现存类来演变成新类,但仍存在复用的可能性。在新类的实现过程中,可以通过引用一些现存类的实例来加快开发速度。例如,表格、硬件接口等都可以作为新类的局部组件使用。
模块、对象和构件
从关注点上来讲,模块关注于代码的组织和复用,对象关注于数据和行为的封装,构件关注于系统的构建和部署。相对来说,构件最显著的特征是其具有较高的独立性,可以独立开发、测试和部署。在其操作上具有可配置的特性,通常可以通过配置来适应不同的环境或需求,而不怎么需要修改其内部代码。
构件复用的四个阶段
基于构件的软件设计方法(CBSD)主要是指从已有的构件库中利用可复用的构件,尽快让系统模块化,从而让系统能够快速开发出来的开发方法。具体可以细分为检索和提取构件、理解和评价构件、对构件进行修改、组装构件模型四个阶段。
检索和提取构件
从构件库中提取寻找构件一般有三种方法,分别是关键字分类法,刻面分类法 和 超文本组织法;
1、关键字分类法
假设我们有一个巨大的图书馆,里面有很多书。为了找到一本特定的书,你可以使用书的标题、作者名或者关键词来搜索。在软件构件库中,关键字分类法就是通过给每个构件打上标签(关键字),比如“数据库连接”、“用户认证”等,然后通过这些关键字来搜索构件。这种方法简单直接,适用于构件有明确标签的情况。
2、刻面分类法
刻面分类法类似于宝石的切面,每个切面代表构件的一个属性或特征。想象一下,我们在挑选宝石,宝石的每个切面都代表它的一个特性,比如颜色、透明度、重量等。在软件构件库中,刻面分类法会根据构件的不同属性(如功能、性能、可靠性等)来组织构件。这样,你可以根据需要的特定属性来选择构件,比如你想要一个“高性能”且“易于维护”的数据库连接构件,就可以通过这两个属性来筛选。
3、超文本组织法
在软件构件库中,超文本组织法就是通过链接(超链接)将相关的构件组织在一起。例如,一个“用户认证”构件可能会链接到“权限控制”和“会话管理”构件,因为这些构件在功能上是相互关联的。这种方法有助于用户在构件之间建立联系,理解它们之间的关系,从而更好地选择和组合构件。
除了以上从构件库中获取构件以外,其他的获取方法还有:通过遗留工程(legacy engineering)进行解构,将具有潜在重用价值的构件提取出来,得到可重用的构件。也可以从市场上购买现成的商业构件,即COTS(Commercial Off-The-Shell)构件。
理解和评价构件
准确地理解构件至关重要。特别是对构件修改使用时,必须要求构件的开发过程遵循公共标准。
逆向工程是理解构件的另一种重要手段。它试图通过对构件的分析,结合领域知识,半自动地,生成相应的设计信息,然后借助设计信息完成
对构件的理解和修改。
对构件进行修改
理想状态是直接复用构件库中现成的构件,但大多数情况下,必须对构件进行或多或少的修改,以应对新需求。
为了减少构件修改的工作量,要求开发人员尽量使构件的功能、行为和接口设计更为抽象化、通用化和参数化。这样,复用者即可通过对实参的选取来调整构件的功能或行为。如果这种调整仍不足以使构件适用于新系统,复用者就必须借助设计信息和文档来修改构件。
修改后的构件存入构件库。
组装构件模型
组装构件通常有三种可供选择的方式。
1、基于功能的组装:
采用子程序调用和参数传递的方式将构件组装起来。开发人员首先应对目标软件系统进行功能分解,将系统分解为强内聚、松耦合的功能模块。然后根据各 模块的功能需求提取构件,对它进行适应性修改后再挂接在上述功能分解框架(framework)中。
2、基于数据的组装
仍然是传统的子程序调用与参数传递。但它所依赖的软件设计方法不再是功能分解,而是面向数据的设计方法,例如,Jackson系统开发方法。这种方法从目标系统的输入、输出数据结构入手,导出程序框架结构,再补充其他细节,最终得到完整的程序结构图。它特别适用于输入、输出数据结构明确的中小型系统,例如商业应用中的文件表格处理。
3、面向对象的组装
如果从类库中检索出来的基类能够完全满足新系统的需求,则可以直接应用。否则,必须以基类为父类,生成相应的子类,以满足新系统的需求。
构件系统体系结构
构件系统体系结构由一组平台决策、一组构件框架和构件框架之间的互操作设计组成。系统体系结构是构建和设计系统的蓝图,而构件是这个蓝图中的构建块,它们共同定义了系统的结构和行为。
简单来说,构件系统的体系结构类似于搭积木,具有可配置、模块化、可替换、动态性的特性。构件系统架构(Component-Based Software Engineering, CBSE)是基于此。
原子构件 通常指的是最小的、不可再分的构件单元,它封装了特定的功能和所需的资源。从这个角度来看,原子构件确实可以被视为一个“小的服务”
构件复用的案例分析
制作可复用的页面在一个软件系统中,如果页面的样式大体一致,整个系统就形成一个统一的风格,便于程序员的开发与维护,也便于用户的使用记忆并给予用户一个整体的美感。
我们代入到一个 “ERP业务系统的设计与实现” 中,一种符合构件复用的设计是,实现一个页面模板,并将模板中的前台和后台代码都分为不变部分和可变部分。在制作一个应用页面时,程序员只要修改其中的可变部分代码即可完成页面的制作。这样,在制作模板页面时,尽可能地将代码写成通用的不变部分,以减少程序员的代码编写量。
页面可以用到3种可复用的构件,分别为数据库访问构件,页面用户控件和自定义控件。
在这个例子中,我们可供分析的信息有:
1)上述案例中的菜单可以作为一种构件(而不只是代码模块或对象),具有标准的表现形式和结构,同时具有独立部署、便于组装的特性。
2)上述案例的复用是对ERP系统领域不同层次的复用,属于垂直复用;
3)我们可以将菜单的抽象实现当成是一个原子构件,由一个菜单项类和一些触发形式、名称、子菜单项组成。其组装的方式倾向于面向对象的组装方式。
4)ERP系统中的菜单具有可配置、模块化、可替换、动态性的特性。在软件开发早起通常由程序员手动实现,目前该类需求已经被替换由主流操作系统的框架(如.NET)实现,通过组合现成的、可互操作的构件来构建实现。
5)以上基于构件的软件工程称之为CBSE