计算机软件构件复用属性规范

作者:云南省计算机应用重点实验室QB-CAKL010516)

 

本规范参照国家《质量管理和质量保证标准第三部分:GB/T 19001-ISO9001在软件开发、供应和维护中的使用指南》GB/ 19000.3-1994 ISO 9000-3-1993,国家《信息技术 软件产品评价 质量特征及使用指南》GB/T 16260-1996,和美国《NATO可复用软件构件库标准》,并具有与《青鸟构件规范》的一致性。

1   目的

本规范为实施《青鸟软件生产线技术的引进、开发、应用和示范工程》而规定以构件复用为目的的构件属性的定义方法。

2   适用范围

本规范适用于计算机软件构件的评价、收集、整理、分类和构件在可复用构件库的登录、查找、修改与撤消。

3   术语

3.1    构件Component)

广义定义:构件是计算机软件构件的简称,是在软件生命周期各阶段可以被复用的软件实体,它可以是设计、代码或软件开发过程的其它产品。如可组装的软件、程序模板、程序的原代码或目标模块和软件需求说明、规格说明、程序说明、数据说明、测试说明和测试案例等软件成分。“复用”指在同一系统的其它地方或另一个系统中使用已有的软件构件[1]

狭义定义:软件构件是具有公开接口和确定意义的可被组装的软件制品。它可以不加修改或者基本不加修改地作为一个部件和其它构件一起组装成更大的软件或软件成分[2]

3.2    构架Framework)

构架是计算机软件构架的简称,是可以复用的、需要再扩展才能实现的“半完成”的软件[3]。构架提供应用域的可扩展的模板[4],它具有完整的结构、基本元件和明确说明接口的组装其它构件或程序的扩展点[5]。构架也是一种构件,可以被组装。本规范用构件的狭义定义区分构件与构架。不加区分时“构件”术语的广义定义包含了它的狭义定义。

扩展点是构架中允许被替换、被修改的功能或程序体位置的明确标识。

3.3    构件的连接关系

一个构件直接与其它构件的继承、关联、访问、存取、引用或通信关系。构件的连接关系有继承关系、聚合关系、联合关系和数据流关系。构件的连接关系简称“连接关系”。

3.3.1       继承关系

继承关系是面向对象的构件的“一般和特殊”关系。通过继承,一个类可以共享另一个类(单一继承)或多个类(多重继承)的结构、属性和方法[6]

3.3.2       聚合关系

聚合关系是构件的“整体和部分”关系。通过聚合,被聚合的构件作为成员组装到聚合构件中,聚合构件应该有方法建立聚合构件和所有被聚合构件的动态的或逻辑的整体一致性[7]。聚合构件和被聚合构件可以是面向对象方法的实例或结构化方法的函数。结构化方法的模块结构用聚合关系表达;文档构件的组合和引用也用聚合关系表达。

 

3.3.3       联合关系

联合关系表达构件之间的联系。“联系”可以是一个构件对别的构件(单向)或者是相互(双向)的关联、访问、存取、引用和通信,聚合关系是一种“强”联合关系[8]。为区分聚合关系与联合关系,本规范约束联合关系仅表达(1)数据结构的关联(如E-R关系);(2)对象的指向关系(一个对象作为另一个构件的方法或函数的参数被引用);(3)文档构件参考资料的指针(参考符)。

3.3.4       数据流关系[9]

数据流关系是基于对象数据流图的一种联合关系,表达对象之间的功能信息关联。同时支持结构化方法和面向对象方法的系统分析与设计。数据流关系用联合关系中的对象的指向关系实现。   

3.4     构件的包含关系

如果构件A被组装到构件B中,并且A或者A的成员可以被构件B所使用,则称构件B包含构件A。本规范定义,构架和构件可以互相包含;面向对象方法的构件和结构化方法的构件也可以互相包含。可复用构件库的结构服从本定义。

3.5    构件属性

3.5.1   说明属性

    综合说明构件的名字、来源、版权信息、版本历史和构件的应用领域、构件类型、开发工具、开发方式、运行环境、主要功能和复用的程度,以及构件查询的关键字。

3.5.2   使用属性

说明构件的应用领域、表达形式、服务类型、开发方式、开发工具、运行环境、可复用程度、被使用的次数、被修改的次数,以及技术、经济或法律的约束条件。

3.5.3   内容属性

内容属性包括构件体和构件的连接关系。构件体即构件本身的内容(程序或文档),不包括该构件所复用的其它构件;构件的连接关系说明该构件复用其它构件的连接关系类型(继承、聚合、联合、数据流),不包括构件体内部的“类”或函数间的关系。

3.5.4   结构属性

定量说明构件的结构特征。它包含构件的服务数、内聚、耦合、结构层数、继承、聚合、函数调用等因子。它支持面向对象方法、结构化方法或二者混合方法开发的构件的结构描述。

3.5.5   评价属性

本规范推荐应用Albrecht复杂度、COCOMO 2.0复杂度和DeMarco复杂度从构件的功能组成角度评估构件的复杂度,用McCabe复杂度和Dhama内聚度从构件内部的程序结构角度评估构件的复杂度。构件的复杂度评估,对于评价构件的质量和预测构件开发、复用、测试、维护的工作量和难度有重要意义。

 

3.5.5.1    功能复杂性[10]

功能复杂性是从构件的规格说明与设计通过构件的功能性来度量构件复杂度的因子。功能复杂性是针对4GL的出现以至不能用简单的代码行作出前述评估而提出的。有三种典型的评估模型可以用于结构化方法、面向对象方法或者混合方法开发的构件功能复杂性评估:

Albrecht复杂度[11],是基于应用(软件或系统)所含的功能和技术要求计算“功能点”的软件复杂性度量。它给出外部输入、外部输出、交互输入、外部文件和内部文件五类三个尺度(简单、平均、复杂)共15个因子计算“非可变功能点复杂性”(UFC,Unadjusted Function point Complexity),又给出14个技术因子计算“技术复杂因素”(TCF, Technical Complexity Factor),“功能点”(FP, Function Point)等于UFC和TCF的乘积,是复杂度评估的基准。

COCOMO 2.0复杂度[12],是组合进“对象点”(OP, Object Point)、“功能点”和“源代码行”(LOC, source Line Of Code)度量覆盖软件生命周期的复杂度度量模型。Boehm推荐应用“对象点”于应用组合(Application Composition)阶段或原型工程,应用“功能点”和“源代码行”于应用开发(Application Development)阶段。“对象点”OP的计算统计应用中所含的屏幕数、报告数(Reports)和3GL构件数,每一种都带有“简单”、“中等”、“困难”三级复杂性权重。引入“复用率”R%,新开发的“对象点”NOP = OP×(100-R) / 100。如果应用“对象点”和“功能点”于同一系统复杂性的早期评估,“对象点”的计算量大约是“功能点”计算量的47%[10]

DeMarco复杂度[13],是基于结构化分析与设计的复杂性度量。它区分应用系统为“功能强”的系统或“数据强”的系统。“功能强”的系统复杂度是基于数据流图(DFD)依据功能类型加权计算系统所含有的功能对象数和功能对象内的输入/输出数据项数;“数据强”的系统复杂度是基于实体关系图(ERD)依据数据实体的关系数加权计算系统所含有的数据实体数。DeMarco建议用数据对象间的数据连接数与功能对象数的比值区分“功能强”的系统(小于0.7)或“数据强”的系统(大于1.5),或是“中性”的系统(0.8和1.4之间)。

3.5.5.2    结构复杂性

结构复杂性是通过构件内部的程序结构对构件的结构复杂度进行度量的因子。McCabe复杂度[14]是典型的适用于结构化方法、面向对象方法或者混合方法开发的构件结构复杂性的评估模型。

McCabe复杂度映射一个程序成为一个图,程序的“基本结构复杂度”为判定节点数加1。基于此,McCabe定义了层次化引用构件的程序的结构复杂度:(1)顺序执行构件的程序结构复杂度等于顺序系列中所有构件的结构复杂度之和减去构件数再加1;(2)嵌套调用构件的程序结构复杂度等于程序的“基本结构复杂度”加上所有被调构件的结构复杂度之和再减去被调构件数。McCabe复杂度是NATO推荐的构件结构复杂性度量模型。对于继承复用,本规范规定不计入被继承构件的复杂度,但被继承构件在被度量构件内部参与运算的方法作为被度量构件的组成成分被度量。

3.5.5.3     Dhama内聚度[22]

Dhama内聚度根据方法或函数的接口参数、全局变量、“扇入”、“扇出”等评估方法或函数的内聚度。Dhama定义内聚度Mc为Mc = K/(di + 2ci + do + 2co + gd+ 2gc + w + r)。这里,数据耦合和控制耦合参数di 是输入参数、ci输入控制参数、do是输出参数、co是输出控制参数,全局耦合参数gd是全局变量数、gc是全局控制变量数,环境耦合参数w 是被调用的函数、r是调用的函数。常数K=1。控制类参数引起引起条件转移,加权2。

4   属性描述语言

属性描述采用巴科斯范式(BNF,Backus Normal Form)描述,本规范使用的描述符号意义如下:

::=    定义符,意为“定义为”。

      连选符,符号两边的内容必须选取(可省略,省略时自然连接的内容必须选取)。

|       选择符,符号两边的内容选择其中一个。

[ ]     任选符,符号内用分隔符分隔的内容可选一个、多个或者不选。

          重复符,符号前任选符包含的内容可以重复一个或多个,或者不重复。

< >     待定义符,符号内的内容需要再定义。

“”        复用定义符,符号内的定义被继承。

5   构件属性

5.1   说明属性

       构件说明属性::= <构件名字><构件来源><版权信息><版本历史><内容摘要><关键字>

        <构件名字>::= 英语名字且唯一+汉语名字

     <构件来源>::= 构件提供者 [+联系人+联系方式+构件提供日期]

        <版权信息>::= <作者名字><版权所有者名字><版本号><出版日期><收录日期>

            <版本号>::= 版权所有者定义的版本号 | CALyymmdd99  [注:本室版权编码]

                     <收录日期>::= 收录进构件库的日期

        <版本历史>::= 文字说明,用逗号“,”分隔的本版本前的版本号系列。

        <内容摘要>::= 文字说明,描述构件的应用领域、构件类型、开发工具、开发方式、

运行环境、主要功能和复用程度。

     <关键字>::= 说明构件的应用领域、类型和重要功能的4个左右的英文词。

5.2   使用属性

    构件使用属性::= <应用领域><构件形式><构件类型><开发方式><开发工具>

<运行环境><复用程度>[10] <使用次数><修改次数><约束申明>

     <应用领域>::= [公共 | PUB] | [办公自动化 | OA] | [电子商贸 | EC] | [其它 | OTHER]

     <构件形式>::= <文档 | DOC>|<源码 | CODE>|<二进制 | BIN>|<工程 | PROJ>

            <文档 | DOC >::= <规格说明 | RSD> | <设计说明 | DAD> | <实现说明 | IMD>

                         | <测试案例 | TCD> | <使用说明 | UD> | <工程书 | PJD>

            <工程书 | PJD>::= [规格说明,设计说明,实现说明,测试案例,使用说明]

            <源码 | CODE >::= 程序的源码形式,参见《构件的程序写作规范》。

            <二进制 | BIN >::= <DLL>|<LIB>|<ActiveX>|<CORBA对象>|<其它>

[注:构件的二进制形式可以通过对<源码 | CODE >的封装、编译而来。如果要编译为LIB(静态库),只要简单的更改源程序的make文件中的输出部分即可。对于Windows平台而言,如果要编译为DLL,只要增加一个定义文件,如interface.def,在其中定义要公开的函数名称即可。如果要编译为ActiveX,可以使用VC中的ActiveX向导生成一个具有相同接口的空ActiveX控件,然后使用源码构件的接口定义ActiveX的接口。如果要编译成CORBA对象,需要使用OMG IDL定义接口,然后使用IDL编译程序得到根程序和程序框架,然后使用源码构件的界面实现CORBA对象。]

            <工程 | PROJ >::= [文档,源码,二进制]

     <构件类型>[15][16]::= <人机界面 | HIC>|<任务构件 | TMC>|<数据访问构件 | DMC>

                        |<数据库接口 | DIC>|<子系统 | SUBS>|<应用系统 | APPS>

            <人机界面 | HIC >::= GUI的“类”、函数、窗口、Web页面、演示等。

            <任务构件 | TMC >::= 在人机界面和数据库接口之间的中间件

            <数据访问构件 | DMC >::= 支持SQL操作(如增、删、修、查等)的构件。

            <数据库接口 | DIC >::= 驱动数据库管理系统命令如连接、断开、事务、回

退、访问等执行的构件。

            <子系统 | SUBS >::= 应用的子系统程序包。

            <应用系统 | APPS >::= 应用系统程序包。

     <开发方式>::= [面向对象 | OO ] | [结构化 | SD ] | [混合 | MIX]

     <开发工具>::= 说明主要的构件开发工具、开发环境和支持软件。

     <运行环境>::= 说明构件运行必须依赖的操作系统、数据库或网络等。

     <复用程度>::= <完全复用>|<小修改复用>|<大修改复用>|<新构件>

            <完全复用>::= 构件的所有代码不加修改的复用

            <小修改复用>::= 构件的操作或代码被修改的量在25%以下

            <大修改复用>::= 构件的操作或代码被修改的量在25%以上

            <新构件>::= 新制作的构件

                 [注:参考资料[10]中的上列经验来自 NASA/Goddard Software Engineering Laboratory]

     <使用次数>::= 构件被使用的次数。新构件为0,每使用一次加1。

        <修改次数>::= 构件被使用者在他的环境下修改的次数。初值为0,每修改一次加1

        <约束申明>::= 构件不能被使用的约束条件,可能是技术的、经济的或法律的约束。

5.3    内容属性

       构件内容属性::= <构件体><构件关系>

       <构件体>::= <构件主体><构件子体>

              <构件主体>::= 不包含它所复用的构件的主程序、基本“类”、主函数等程序体

              <构件子体>::= 构件本身不包含它所复用的构件除了构件主体以外的其它程序体

       <构件关系>::= [“构件主体”复用的“构件名字”+ <构件的连接关系> ] …

              <构件的连接关系>::= <连接关系>

              <连接关系>::= 继承关系 | 聚合关系 | 联合关系 | 数据流关系

5.4    结构属性 [17] [10] [18][19][20]

       构件结构属性::= <服务数><方法/函数><结构层数>

                                     <继承类数><继承重数><最大继承深度><平均继承深度>

                                     <聚合对象数><联合对象数><耦合度><低内聚度>

        <服务数>::= 构件本身和它复用的构件提供服务的方法数

                                   | 构件本身和它所复用的构件直接存取外部数据的函数、方法数

                                   | 构件本身和它所复用的构件的子系统数和所有子系统“功能点”总数

        <方法/函数>::= 构件本身和它复用的构件在构件主体中实例化的方法数或函数

        <结构层数>::= 构件本身(不包括复用构件)的结构化层次数。

        <继承类数>::= 所有的被构件主体继承的继承“树”的“类”的总和。

        <继承重数>::= 所有的被构件主体继承的继承“树”的根节点数。

        <最大继承深度>::= 所有的继承“树”的从根节点到叶节点的最长路径之

        <平均继承深度>::= “继承类数”除以“最大继承深度”。

        <聚合对象数>::= 构件主体聚合的“类”的实例数。

        <联合对象数>::= 构件主体的方法或函数在参数表中引用的“类”的实例数。

        <耦合度>::= “继承重数”乘以“平均继承深度”与“聚合对象数”、“联合对象数”

        <低内聚度>::= 构件主体中每个方法(或函数)、实例方法存取属性(或变量)的“属

性变量集进行“交”运算所形成的不相交集的个数。

5.5    评价属性

       构件评价属性::= <功能复杂性><结构复杂性>

         <功能复杂性>::= Albrecht复杂度 | COCOMO 2.0复杂度 | DeMarco复杂度

[注:COCOMO 2.0复杂度的评价指标:“屏幕表示数”(Number of screen view)是一个用户窗口中所含的数据输入和数据显示区的个数;“报告数”(Number of report)是在屏幕或打印机输出的报表数和输出的文件或数据库“表”数;“3GL构件数”是用户界面上产生操作命令的对象数。]

         <结构复杂性>::= McCabe复杂度

[注:McCabe复杂度映射一个程序成为一个结构图,图中用白点表示程序中没有调用关系的节点,用黑点表示调用了一个子程序的节点。程序的“基本结构复杂度”为判定节点数加1。图的简化规则是a. 减去白点,保留黑点;b. 对于程序中的循环结构体、分支结构体和嵌套结构体(包括递归),计算结构体的“基本结构复杂度”,再加1c. 对于黑点表示的子程序结构体,计算子程序的“基本结构复杂度”,再加1d. 在结构体内如果有相同子程序的调用,所有相同子程序的复杂度只计算1次;e. 整体结构复杂度是结构化的各子结构复杂度的和]

6   构架属性

6.1    说明属性

    构架说明属性::=  “构件说明属性”

6.2    使用属性

    构架使用属性::=  “构件使用属性”

6.3    内容属性

    构架内容属性::= “构件内容属性”

6.4    结构属性

    构架结构属性::= “构件结构属性”+ <扩展点数>[21]

        <扩展点数>::= 构架中提供给用户自定义或自实现的操作或功能数。

6.5   评价属性

    构架评价属性::= “构件评价属性”

7     叶类属性

定义只提供服务的“类”构件,即没有复用连接关系的“类” 构件的属性。因为它处于复用的低层,所以称之为“叶类”构件。它们的特征是粒度小、具有公共功能和接口。为很多构件复用。

7.1    说明属性

    “类”说明属性::=  “构件说明属性”

7.2    使用属性

       “类”使用属性::=  构件使用属性

7.3    内容属性

    “类”内容属性::= “构件体”

7.4    结构属性

    “类”结构属性::= “构件结构属性”

7.5    评价属性

       “类”评价属性::= “构件评价属性”

 

8   叶方法属性

定义只提供服务的方法或函数的构件,它们没有复用连接关系。因为它处于复用的低层,所以称之为“叶方法”构件。特征是粒度小、具有公共功能和接口。为很多构件复用。

8.1    说明属性

方法说明属性::=  “构件说明属性”

8.2   使用属性

    方法使用属性::=  “构件使用属性”

8.3    内容属性

    方法内容属性::= “构件体”

8.5    结构属性

方法结构属性::= <方法内聚度>[22]

        <方法内聚度>::= Dhama内聚度

8.6    评价属性

    方法评价属性::= McCabe复杂度

9   附则

本规范由“青鸟生产线技术引进、开发、应用、示范”项目组负责解释并执行。

10   参考资料

[1] NATO Standard for Management of A Reusable Software Component Library, issued and maintained by NATO Communication and Information System Agency

[2] Jon Hopkins, Component Primer (see definitions of D.D’Souza and A.C.Wills, and B.Meyer et al), Communications of ACM, October 2000-Volume 43, Number 10.

[3] Mohamed E. Fayad and Douglas C. Schmidt, Object-Oriented Application Frameworks, Communications of the ACM, October 1997, V0l. 40, No, 10.

[4] Grady Booch, The Unified Modeling Language User Guide, Addison Wesley, Reading, MA, USA, 1998.

[5] D. D’Souza and A. C. Wills, Objects, Components and Frameworks with UML: The Catalysis Approach. Addison Wesley, Reading, MA, USA, 1999.

[6] Grady Booch, Object-Oriented Analysis and Design with Applications, Addision Wesley, Reading, MA, USA, 1994.

[7] Richard C. Lee and William M. Tepfenhart, UML and C++: A Practical Guide to Object-Oriented Development, Prentice Hall, Reading, NJ, USA, 1997.

[8] Ivar Jacobson, Martin Griss and Patrik Jonsson, Software Reuse: Architecture, Process and Organization for Business Success, Addison Wesley, Reading, NY, USA, 1997.

[9] Roger S. Pressman, Software Engineering: A Practitioner’s Approach, 4th Edition, Reading, the McGraw-Hill Companies, Inc. NY, 1997.

[10] Norman E. Fenton and Shari L. Pfleeger, Software Metrics: A Rigorous & Practical Approach, International Thomson Computer Press, 2nd Edition, Reading, London, UK, 1997.

[11] Albrecht A. J., Measuring Application Development Productivity, Proceedings, IBM Application Development Symposium, Monterey, CA, October 1979.

[12] Barry Boehm et al., Cost Model for Future Software Life Cycle Processes: COCOMO 2.0, Annals of Software Engineering 1(1), November 1995.

[13] DeMarco T., Controlling Software Projects, Reading, Yourdon Press, NY, 1982.

[14] Thomas J. McCabe and Charles W. Butler, Design Complexity Measurement and Testing, Communications of the ACM, December 1989, Volume 32 Number 12.

[15] Coad P. and E. Yourdon, Object-Oriented Design, Reading, Prentice-Hill, 1991.

[16] E. Yourdon, Object-Oriented System Design: An Integrated Approach, Reading, Prentice-Hill, 1994.

[17] Chidamber S. R. and Kemerer C. F., A Metrics Suite for Object-Oriented Design, IEEE Trans. Software Engineering, Vol. 20, no. 6, June 1994.

[18] Bansiya J., Evaluating Framework Architecture Structural Stability, ACM Computing Surveys, vol. 32, no. 1, 2000.

[19] Lionel C. Briand, John W. Daly and Juren Wust, A Unified Framework for Cohesion Measurement in Object-Oriented Systems, Reading, ISERN-97-05, Fraunhofer Institute for Experimental Software Engineering, Kaiserslautem, Germany.

[20] Lionel C. Briand, John W. Daly and Juren Wust, A Unified Framework for Coupling Measurement in Object-Oriented Systems, Reading, ISERN-96-14, Fraunhofer Institute for Experimental Software Engineering, Kaiserslautem, Germany.

[21] Ivar Jacobson, Martin Griss and Patrik Jonsson, Software Reuse: Architecture, Process and Organization for Business Success, Reading, Addison Wesley Longman, NY, 1997.

[22] H. Dhama, Quantitative Models of Cohesion and Coupling in Software, Journal of System and Software, vol. 29, no. 4, April 1995.


计算机软件构件复用属性规范的说明

作者:丁志强  教授  Email: dingzq@public.km.yn.cn

二○○一年五月十六日

 

《计算机软件构件复用属性规范》(QB-CAKL010516,简称“属性规范”)是为实施《青鸟软件生产线技术的引进、开发、应用和示范工程》而制定的项目组标准,它对于计算机软件构件的开发有重要的指导作用,对已经存在的软件构件的评价、收集、整理、分类和构件库的建设、维护及构件查找具有使用价值。《属性规范》是对《青鸟构件规范》的较大程度的补充,并使许多相关的理论、方法、标准具体化。《属性规范》是一个可操作的标准。《属性规范》不仅在青鸟引进项目中发挥了最重要的作用,而且,将在该项目的完善和长期的构件研究和开发中发挥指导作用。本规范的制定参照了国家《质量管理和质量保证标准第三部分:GB/T 19001-ISO9001在软件开发、供应和维护中的使用指南》GB/ 19000.3-1994 ISO 9000-3-1993,国家《信息技术 软件产品评价 质量特征及使用指南》GB/T 16260-1996,和美国《NATO可复用软件构件库标准》,并具有与《青鸟构件规范》的一致性。本文对该规范中重要的内容、新的定义、可能有多义的解释之处加以说明。

 

一、术语

1.关于构件和构架

在“复用”研究中,构件和构架经常出现混淆。例如,有些专家把Architecture和Framework看作构架,有些专家把Framework看作Template。NATO只定义了Component,没有定义Framework。但有一个共同的看法,把Architecture看作工程初期的满足需求的顶级系统总体结构,把Framework或Template看作可以扩展或修改的“半成品”,把Component看作可以软件成分。为使这些词在我们自己的工程中具有确定的无歧义的术语,我们把Architecture限定为“领域结构”(Domain Architecture),是领域构件设计或实现的形式化的规格说明(参见《可复用构件开发导则》,QB-CAKL010518);把Framework定义为构架;把Component定义为构件。本规范综合杨芙清、NATO、D. DSouza和A. C. Wills、B. Meyer、M. E. Fayad和D. C. Schmidt、G. Booch等的定义,对构件、构架作出了明确的定义:

构件Component)

广义定义:构件是计算机软件构件的简称,是在软件生命周期各阶段可以被复用的软件实体,它可以是设计、代码或软件开发过程的其它产品。如可组装的软件、程序模板、程序的原代码或目标模块和软件需求说明、规格说明、程序说明、数据说明、测试说明和测试案例等软件成分。“复用”指在同一系统的其它地方或另一个系统中使用已有的软件构件。

狭义定义:软件构件是具有公开接口和确定意义的可被组装的软件制品。它可以不加修改或者基本不加修改地作为一个部件和其它构件一起组装成更大的软件或软件成分。

构架Framework)

构架是计算机软件构架的简称,是可以复用的、需要再扩展才能实现的“半完成”的软件。构架提供应用域的可扩展的模板,它具有完整的结构、基本元件和明确说明接口的组装其它构件或程序的扩展点。构架也是一种构件,可以被组装。本规范用构件的狭义定义区分构件与构架。不加区分时“构件”术语的广义定义包含了它的狭义定义。

构件用了“广义定义”和“狭义定义”,前者强调构件的成分,后者是近来出现的定义,其意在于用“不加修改”和“半完成”作为准则区分“构件”和“构架”,构件的“基本不加修改”是我们补充上的,因为很多构件的复用需要修改(才会有“修改复用”一说)。怎样区分构件和构架的修改?我们在构架中定义了“它具有完整的结构、基本元件和明确说明接口的组装其它构件或程序的扩展点”,构架的修改是在明确定义的“扩展点”进行针对功能或具有完整程序体结构的修改或扩展;构件的修改是针对某个程序片段的修改,以增强构件的适应性,构件中可以修改的程序片段,也必须在构件体中的允许修改位置加以注释(参见《可复用构件开发导则》,QB-CAKL010518)。

2.关于结构化方法和面向对象方法

结构化方法和面向对象方法的争执现在已经有了结论。Booch曾经武断地说面向对象方法不支持结构化方法,然而,他的方法论把分析与设计、设计与实现放在一个“扁平”的(不能结构化分解的)图中表达,有悖人的认知规律,再加上“继承”泛滥使用,使程序对程序的依赖很难控制,受到了强烈挑战。James Rumbaugh等试图解决这一问题,在他们的OMT方法中引入了数据流图建立功能模型,但没有说怎样建立功能模型和对象模型之间联系。Ivar Jacobson等用USE CASE作为工程前期分析工具,提出了OOSE方法,在结构化方法和“扁平”式面向对象方法之间做了折衷。现在这三种方法被集成在一个环境中(Rational Rose),叫“统一建模语言”(UML)。结构化方法的提出者Edward Yourdon认为面向对象方法应用了结构化原理,他在他提出OOA方法时说出了这个道理。

我们认为面向对象的“封装”和“类型”继承了结构化的机制,如C语言中的structure;面向对象的“聚合”是“类型”机制的应用;面向对象的“联合”是结构化E-R模型的发展(把数据实体重定义为对象实体,完全沿用原来的实体关系);面向对象的“继承”才是它独有的机制,然而“继承”没有结构化的层间控制,如果滥用可能造成程序总体结构的不稳定。但是,面向对象方法把对象的属性和操作封装在一起作为一个分析或设计的实体,并且已经有了很多OOP语言支持它的实现,使得面向对象的建模比结构化建模更接近于现实,而且,OO模型可以直接用OOP实现,解决了结构化模型不能直接过渡到实现的难题。

我们认为可以用面向对象的“聚合”机制实现结构化的分解,同时OOP也支持在结构化的函数中用“类”类型定义实例变量。所以,用结构化方法也可以从分析、设计到实现成为面向对象的。

从方法论角度讲,我们提出用结构化方法实施工程前期的分析与设计,用面向对象方法实施工程后期的设计与实现。同时,我们提出在工程前期“不设计实现”的原则,这个原则如果应用于面向对象方法,那么当应用面向对象方法在复用工程前期的领域分析时,不使用“继承”机制和“聚合”机制(除非它被用于分析的分解或集成),这两个机制只在设计和实现阶段使用(参见《可复用构件开发导则》,QB-CAKL010518)。

《属性规范》的属性除个别外均对结构化方法和面向对象有效。 “方法” 和“函数”的属性处于同等地位被研究,在规范中加以定义和描述。“聚合”在结构化方法中被用来表达结构的分解或集成。

3.“聚合”与“联合”

“联合”的E-R关系在OOP中没有明显的编程机制支持,可以用多种算法实现。“聚合”也是实现“继承”的一种算法。为了在构件的连接关系属性中区分“继承”与“聚合”,规范“约束联合关系仅表达(1)数据结构的关联(如E-R关系);(2)对象的指向关系(一个对象作为另一个构件的方法或函数的参数被引用);(3)文档构件参考资料的指针(参考符)”。

4.构件的包含关系

《属性规范》定义,“构架和构件可以互相包含;面向对象方法的构件和结构化方法的构件也可以互相包含”。基于构架的定义和构件的狭义定义,二者都是一个结构体中可以被组装的部件,因此可以互相包含。面向对象结构自身具有包含结构化结构的机制(如函数在“类”的方法中被调用)。结构化方法包含面向对象的方法,一是在结构化分析或设计之后的实现,二是在结构化程序的实现中用“类”类型定义实例变量。这就产生了构件开发方式中的第三中方式:“混合”开发方式。

 

二、构件说明属性

《属性规范》规定了在说明属性中要记录“版本历史”。版本历史用文字说明,依时间序同一构件的每个版本号用逗号“,”分隔。这一规定对于版本管理很有意义。规定说明:1构件的历史版本在构件库中必须保留,不能用新版本代替老版本;2版本历史具有追朔老版本的适用价值。

“内容摘要” 描述构件的应用领域、构件类型、开发工具、开发方式、运行环境、主要功能和复用程度。已经在构件库的查询首页显示在每个构件名字下面。

“关键字”继承了青鸟构件库的查询手段。

 

三、构件使用属性

1.构件的分类

    根据我们当前的构件情况,把构件按两个层次分类。第一层是按应用领域分为“公共”领域、“办公自动化”领域、“电子商贸”领域和“其它”领域;在每个应用领域下是第二层,按构件类型分为“人机界面”、“任务构件”、“数据访问构件”、“数据库接口”、“子系统”构件和“应用系统”。前五个是Yourdon分类的修改,其修改点是把Yourdon的数据管理层分为“数据访问构件”、“数据库接口”两层,它们支持多层次体系结构的开发,增强了构件的复用性。后两个是我们的补充。事实上,我们开发的电子商贸子系统,对界面形式和数据库接口的依赖性很小,子系统可以称为构件被复用。

2.关于构件形式

    应用构件的广义定义,构件有多种形式。规范定义了两类。第一类是文档,有“规格说明”、“设计说明”、“实现说明”、“测试案例”、“使用说明”和“工程书”几种形式,工程书是它前面所有形式构件的可选集合。第二类是代码,有“源码”和“二进制码”。构件的二进制形式可以通过对源码的封装、编译而来。如果要编译为LIB(静态库),只要简单的更改源程序的make文件中的输出部分即可。对于Windows平台而言,如果要编译为DLL,只要增加一个定义文件,如interface.def,在其中定义要公开的函数名称即可。如果要编译为ActiveX,可以使用VC中的ActiveX向导生成一个具有相同接口的空ActiveX控件,然后使用源码构件的接口定义ActiveX的接口。如果要编译成CORBA对象,需要使用OMG IDL定义接口,然后使用IDL编译程序得到根程序和程序框架,然后使用源码构件的界面实现CORBA对象。

3.关于复用程度

    规范定义了构件的复用程度有“完全复用”(构件的所有代码不加修改的复用)、“小修改复用”(构件的操作或代码被修改的量在25%)、“大修改复用”(构件的操作或代码被修改的量在25%以上)和“新构件”(新制作的构件)四个等级。该定义来源于NASA Goddard的软件工程实验室。但我们作了补充,即把构件中的“操作”(例如,方法、函数、人机界面的对象、文件、输出的对象等)被修改的个数作为“修改量”。这个补充既适应了4GL开发方式,也适应复杂构件的计量。用被修改的代码行作为“修改量”计量,仅使用于简单的、功能极少的构件。任何时候,两种计量方法只能选择一种。

4.使用次数和修改次数

使用次数和修改次数引用于青鸟构件规范。是评价构件被复用概率的指标。它们要求构件库的维护。但很难做到“每使用一次加1”,做得到的是“每查看一次加1”。

5.约束声明

从构件使用的安全性和合法性角度,给出构件的“约束声明”是很重要的,“约束声明”公开表明构件不能被使用的约束条件,它们可能是技术的、经济的或法律的约束。如果构件的使用没有任何约束,“约束声明”属性也不能空白,必须填“无”。

 

四、构件体、构件主体和构件子体

构件内容属性表达构件实体本身,及该构件如果复用了其它构件时该构件与其它构件的连接关系。构件库依据这个属性放置该构件本身,并建立该构件与其它被复用构件的链接路径。

该属性定义中引入了“构件体”、“构件主体”和“构件子体”的概念。构件体就是构件本身,由构件主体和构件子体组成。构件主体是不包含它所复用的构件的主程序、基本“类”、主函数等程序体;构件子体是构件本身(不包含它所复用的构件)除了构件主体以外的其它程序体。区分出构件主体很重要,所有被复用的构件以及构件子体都必然以对象实例、变量实例、方法或函数的形式在构件主体中表现出来(只要构件是“内聚”的)。所以,很多构件结构属性的评价都是针对构件主体进行的。

 

五、构件结构属性

构件结构属性是对构件内部结构进行“白盒评价”的指标体系,它对于判断一个构件是否可复用、评价一个构件的可复用程度具有及其重要的作用。下列指标的制定吸收了很多专家的思想和方法。主要有:源于Albrecht和Boehm为适应4GL先进开发提出的“功能点”、“对象点”思想对“服务数”指标作了补充;基于Bansiya对构架结构稳定性评价指标体系的研究,引用了“结构层数”、“继承类数”、“继承重数”、“最大继承深度”、“平均继承深度”的算法,但加以构件体(构件本身)、构件主体的定义避免理解的歧义使计算更准确,舍弃了Bansiya的“类的个数”(构件体中所有类必在构件主体中实例化,用“构件的方法/函数”替代)、“父类个数”(同上理)、“继承平均宽度”(这是一个狭义的间接指标,用“聚合对象数”、“联合对象数”、“调用函数数”替代)、“直接类耦合数”(我们的定义已经形式化)等指标;基于Briand等对多种“内聚”度量方法的比较研究,我们选取了Chidamber和Kemerer的“低内聚度”CK模型,并对他们的两种模型选取了目前可操作的一种。在《可复用构件开发导则》QB-CAKL010518中我们给出了评价这些指标的经验数据。

1.构件的“服务数”

    “服务数”有三种定义。“构件本身和它复用的构件提供服务的方法数”适用于面向对象构件;“构件本身和它所复用的构件直接存取外部数据的函数、方法数” 适用于结构化方法开发的构件;“构件本身和它所复用的构件的子系统数和所有子系统‘功能点’总数”适用于4GL开发的子系统构件。

2.构件的方法/函数

“构件的方法/函数”定义为构件本身和它复用的构件在构件主体中实例化的方法或调用的函数。定义把分析、计数的边界限制在构件主体内,是一个自包含的定义。“构件的方法/函数”表达了构件的“尺寸”。

3.结构层数

“结构层数”定义为构件本身(不包括复用构件)的结构化层次数。即使面向对象的构件内部也是结构化的。好的构件层次不宜太多。

4.继承类数

“继承类数”定义为所有的被构件主体继承的继承“树”的“类”的总和。这个定义不是自包含的,除了计算构件体本身,还要计算它所复用的构件,但是它所复用的每个构件自己的属性表中已经有该构件的“继承类数”,可以引用。“继承类数”太大,说明构件可能过于复杂。

5.继承重数

“继承重数”定义为所有的被构件主体继承的继承“树”的根节点数。这是自包含定义。“继承重数” 太大,说明构件可能过于复杂。

6.最大继承深度

“最大继承深度”定义为所有的继承“树”的从根节点到叶节点的最长路径之。“最大继承深度”太大,说明构件可能过于复杂。

7.平均继承深度

“平均继承深度”定义为“继承类数”除以“最大继承深度”。这是评价“继承”的综合指标。值越小越好。

8.聚合对象数

“聚合对象数”定义为构件主体聚合的“类”的实例数。这是自包含定义。“聚合对象数”太大,说明构件可能过于复杂。

9.联合对象数

“联合对象数”定义为构件主体的方法或函数在参数表中引用的“类”的实例数。这是自包含定义。“联合对象数” 太大,说明构件可能过于复杂。

10.耦合度

“耦合度”定义为“继承重数”乘以“平均继承深度”与“聚合对象数”、“联合对象数”、“调用函数数”之。这是评价构件主体对其构件子体和其它构件的依赖程度的综合指标。“耦合度” 太大,说明构件可能过于复杂。

11.低内聚度

低内聚度定义为构件主体的每个方法(或函数)、实例的方法存取属性(或变量)的“属性变量集”进行“交”运算所形成的不相交集的个数。值越大,构件的内聚越低。

Chidamber和Kemerer 1991年提出的“低内聚度”CK模型是:

如果类C1有方法M1, M2, …, Mn, 使用方法Mi的实例变量集为{li}, 有n集{l1}, {l2},…,{ln}存在,那么,“低内聚度”(即缺乏内聚的程度)LCOM定义为n集{l1}, {l2},…,{ln}相交运算后所形成的不相交集的个数。

Chidamber和Kemerer 1994提出的“低内聚度”CK模型是:

如果类C1有方法M1, M2, …, Mn, 使用方法Mi的实例变量集为{li}, 有n集{l1}, {l2},…,{ln}存在,让P = {( li , lj )| li Ç∩ lj = Æ}, Q = {( li , lj ) | li Ç ljÆ}, 如果| P | > |Q| 那么LCOM = | P | - |Q|,否则LCOM等于零。可以理解为把实例变量集两两比较,P是不相交的方法对的数,Q是相交的方法对的数,LCOM等于P减去Q。1994CK模型比1991CK模型更精确。但是,1994CK模型的易理解性不如1991CK模型。从可操作的角度,我们目前采用了1991CK模型。

 

六、复杂度评价属性的适用

《属性规范》推荐应用Albrecht复杂度、COCOMO 2.0复杂度和DeMarco复杂度从构件的功能组成角度评估构件的复杂度,用McCabe复杂度和Dhama内聚度从构件内部的程序结构角度评估构件的复杂度。构件的复杂度评估,对于评价构件的质量和预测构件开发、复用、测试、维护的工作量和难度有重要意义。

Albrecht复杂度、COCOMO 2.0复杂度和DeMarco复杂度通常在系统分析获得需求说明时,或在系统设计获得实现的规格说明时,计算系统的功能点或对象点,以预测系统开发的工作量和难度。也在面对一个已经存在的复杂系统或复杂程序时,进行“黑盒评估”时使用。使用起来最直观的是Boehm的COCOMO 2.0复杂度,只统计应用中所含的屏幕数、报告数(Reports)和3GL构件数(称“对象点”)。Albrecht复杂度除计算外部输入、外部输出、交互输入、外部文件和内部文件五类三个尺度的15个因子的“非可变功能点复杂性”外,还要计算14个 “技术复杂因素”,这14个技术复杂因素的权值需要企业长期应用经验的积累。NASA软件工程实验室的统计表明,“对象点”的计算量大约是“功能点”计算量的47%。Albrecht复杂度、COCOMO 2.0复杂度都经过数十个软件企业的数据实测,有很高的可信度。DeMarco复杂度是结构化分析与设计的复杂性度量,基于DFD和E-R图,其度量的时机后于前两种模型。

COCOMO 2.0复杂度我们对它的三个指标进行了无歧义的工程化定义。“屏幕表示数”(Number of screen view)是一个用户窗口中所含的数据输入和数据显示区的个数;“报告数”(Number of report)是在屏幕或打印机输出的报表数和输出的文件或数据库“表”数;“3GL构件数”是用户界面上产生操作命令的对象数。

McCabe复杂度和Dhama内聚度从构件内部的结构进行“白盒评估”。

最有价值的是McCabe复杂度模型。McCabe复杂度映射一个程序成为一个结构图,图中用白点表示程序中没有调用关系的节点,用黑点表示调用了一个子程序的节点。程序的“基本结构复杂度”为判定节点数加1。图的简化规则是a. 减去白点,保留黑点;b. 对于程序中的循环结构体、分支结构体和嵌套结构体(包括递归),计算结构体的“基本结构复杂度”,再加1;c. 对于黑点表示的子程序结构体,计算子程序的“基本结构复杂度”,再加1;d. 在结构体内如果有相同子程序的调用,所有相同子程序的复杂度只计算1次;整体结构复杂度是结构化的各子结构复杂度的和。

 Dhama内聚度对于评价方法或函数的接口是否标准化具有指导意义,其思想作为开发导则写入到我们的《可复用构件开发导则》(QB-CAKL010518)中。

七、构架的扩展点

在领域分析时,某些领域结构中的某些功能的需求可能不确定,或者在构件设计时追求构件的柔性化某些方法可能演变为其它的方法,就把这类功能或方法定义为构架的“扩展点”,在规格说明中或在构架结构体中用“Begin-end对”表示。“Begin-end对”的内容可以在构架被复用时演化、扩展或修改。

 

八、叶类和叶方法构件

构件可以再复用构件。然而,有一些构件粒度小、复用面广,通常是公共领域的基础构件,如我们开发的CGI用户界面构件、数据库接口构件和数据库访问构架,它们不再复用其它构件。把这类构件区分出来,叫作“叶类构件”和“叶方法构件”,有利于提高构件库的可复用性。

 

有关构件评价属性规范的研究问题还很多,例如构件配置管理的属性、构件版本管理的属性、构件质量测试的属性等等,还需要继续研究;即使现在研究出的东西,也还有很多需要继续研究的东西,例如属性的实践验证、用于属性评价的自动化工具开发等等。希望读者提出宝贵意见。


 

可复用构件开发导则

作者:云南省计算机应用重点实验室QB-CAKL010518

 

本规范参照GB 8566-88 《计算机软件开发规范》、《NATO可复用软件构件开发标准》和《NATO软件复用过程标准》,并具有与《青鸟构件规范》的一致性。本规范是对200012月“软件开发导则”的补充和修订。

1  目的

本规范为实施《青鸟软件生产线技术的引进、开发、应用和示范工程》而制定以构件复用为目的的计算机软件构件开发过程所参照的方法和原则。

2  适用范围

本规范作为计算机软件构件开发的参考。

3  术语

3.1   复用的软件工程[1]

复用的软件工程是四个概念的集合:经营、工程、技术和再工程。“经营”概念强调复用的动机来自于商业目的,是否启动一个复用活动,首先要评估该活动可能引起的开发的“成本-效益”和市场的“时间-效益”;“工程”的概念分解复用活动为三个部分:面向领域的体系结构的建立和复用构件系统的提取、面向对象的可复用构件的开发、面向应用的可复用构件的应用;“技术”的概念卷入了一系列的开发模式,它们覆盖体系结构、分析、设计、测试和编码过程的系统化结构,可以向前或向后跟踪以至改变可以在整个结构中得到反映,强调“复用不仅仅是编码的复用”;“再工程”把逆向工程、重构和正向工程组合起来,将现存系统重新构造成为新的形式[2],它决定了复用组织将在什么方向展开,如,现存软件系统将如何被更易于理解、更适应变化的方法提炼出可复用构架和构件?如何维护现存的软件构件以延长其生存期?等等。

3.2   复用

复用是同一系统的其它地方或另一个系统中使用已有的软件构件的过程[3]

3.3   可复用构件

可复用构件指在软件生命周期各阶段可以被复用的软件实体,它可以是设计、代码或软件开发过程的其它产品。如可组装的软件、程序模板、程序的原代码或目标模块和软件需求说明、规格说明、程序说明、数据说明、测试说明和测试案例等软件成分[3]

3.4   领域工程

领域工程是为一组相似或相近系统的应用工程建立基本能力和必备基础的过程,它覆盖了建立可复用软件构件的所有活动。领域是指一组具有相似或相近需求的应用系统所覆盖的功能区域。领域工程包含三个主要阶段:领域分析、领域设计和领域实现[2]。领域工程可能应用于领域中可复用构件的开发,也可能应用于领域中某个应用系统的开发。前者有助于从相似或相近系统的应用工程中获取可复用需求;后者有助于迅速、准确地从构件库中获取可复用构件。

 

4   领域分析

领域分析的主要目标是获得领域模型。该模型描述领域中系统之间的共同需求。领域分析的主要活动有确定领域边界、确定领域需求、建立领域模型、提炼复用需求与构架和评估领域模型。

4.1   确定领域边界

确定领域边界指针对某个应用领域画定其自动化实现的边界的活动,即从某个应用领域中区分出人工实现的对象,把它们划出领域边界之外并标出它们与领域的关系。一个应用领域可能会组合进可以归于其它应用领域的某些对象,例如“电子商贸”中企业内部的文件流转可能利用“办公自动化”的文件管理对象。一个应用领域中对象,有些是可能再领域内不同部分发挥作用的对象,例如“销售传票”出现在定货、出库和送货等过程。以下,分别给出两个导则:

4.1.1    区分领域内的其它领域边界

某领域分析的初期,列出了该领域内的功能对象集。基于复用的目的,把该功能对象集与已经存在或可以预见的其它领域的功能对象集相比较,把在交集中的对象归于其它领域。该功能对象集减去所有该功能对象集与其它领域功能对象集的交集的差,称为该领域的“特有对象子集”。该功能对象集与其它领域功能对象集的交集统称“其它领域对象子集”。

4.1.2   区分领域内的可复用边界

基于复用的目的,在某领域的“特有对象子集”中,把具有相同或相似的处理的对象(考察它们的功能与数据内容)归集到一起,而得到一个个“可能复用对象子集”,余下的对象统称“可能非复用对象子集”。这一工作结果将为以下步骤所利用。

4.2    确定领域需求

确定领域需求基于领域边界划分的结果:组成某领域功能对象集的“特有对象子集”和“其它领域对象子集”,组成该领域“特有对象子集”的“可能复用对象子集”和“可能非复用对象子集”。一般来说,某领域功能对象集不能反映该领域的复用开发需求,因为某些对象可能是某个需求的实例。有必要对各个子集的对象进行归类,提取最简明的领域需求。列出某个需求将实例化为那些对象。特别地,有以下两个导则:

4.2.1    隔离属于其它领域的需求

对组成某领域功能对象集的“特有对象子集”和“其它领域对象子集” 的对象进行归类,提取最简明的领域需求。这里,对前一步骤的结果有一复审过程:在对“其它领域对象子集” 的对象进行归类的基础上,到已经存在的其它领域的功能对象集中检查是否有相同的对象“类”,或者对其它领域进行可预见的分析检查是否可能建立相同的对象“类”,如果回答是不确定的,那么,有必要回到前一步骤,重新划分“特有对象子集”和“其它领域对象子集”。结果得到确定的“特有对象类集”和“其它领域对象类集”。

4.2.2    区分领域内的可复用需求

对某领域的“可能复用对象子集”的对象进行归类,提取最简明的领域需求。类似的,对前一步骤的结果也有一复审过程:在对象归类的基础上,到已经存在的本领域的功能对象集中检查是否有相同的对象“类”,或者对本领域进行可预见的分析检查是否可能建立相同的对象“类”,如果回答是不确定的,那么,有必要回到前一步骤,重新划分“可能复用对象子集”和“可能非复用对象子集”。结果得到确定的本领域的“可复用对象类集”和“非复用对象类集”。

4.3    建立领域模型

基于前一步骤的结果,根据领域特征,可以使用面向对象或面向功能的方法建立领域关系模型。使用那种方法,可参考DeMarco复杂度[4]判断(“数据强”的领域可用面向对象方法,“功能强”的领域可用面向功能方法)。也参见《计算机软件构件复用属性规范(QB-CAKL010516)》。

4.3.1    面向对象的关系模型

以领域的对象类为基本元件,用面向对象的方法建立各对象类之间的关系模型。这里的关系主要是对象类之间的“联合关系”(参见4.4.5节)。注意,领域模型必须保持上一步骤所划定的“特有对象类集”和“其它领域对象类集”边界;在“特有对象类集”内保持上一步骤所划定的“可复用对象类集”和“非复用对象类集”边界。

4.3.2    面向功能的关系模型

以领域的对象类为基本元件,用面向功能的方法建立各对象类之间的关系模型。这里的关系主要是对象类之间的“信息-功能关系”即“信息流关系”,参见《计算机软件构件复用属性规范(QB-CAKL010516)》)。注意,领域模型必须保持上一步骤所划定的“特有对象类集”和“其它领域对象类集”边界;在“特有对象类集”内保持上一步骤所划定的“可复用对象类集”和“非复用对象类集”边界。

4.3.3    优先提炼数据存储对象的原则

建立稳定的数据存储对象是保证应用系统整体稳定性关键的因素[5],所以在领域分析中应优先提炼数据存储对象。在建立领域模型时,数据存储对象作为独立的“联合对象”插入在其它相关对象之间,建立其它相关对象之间的“联合关系”或“信息流关系”。

4.3.4    对称性检查原则

领域模型通常用图形符号表达。表达领域模型时,应注意到把领域中的“可复用对象类集”中相同或相似的对象类在全图中对称排放,有利于在下一步提炼出一个个公共的可复用结构。这是一种形式检查,也是对“可复用”提炼的复审。一个领域模型,如果根本找不到相同或相似的对象类,说明该领域模型内部的可复用程度很差。

4.4    提炼领域结构

领域模型的每一个对象类都将由称为“领域结构”的一个或一套程序或子系统来实现它。领域结构(Domain Architecture)是领域构件设计或实现的形式化的规格说明,在不至于混淆时简称“结构”。然而,并不是每一个对象类的程序或子系统都必须由一个单独的领域结构来说明,这是因为一组相同或相似的对象类可能用一个公共的领域结构来说明它们的公共部分。下面是应注意的导则:

4.4.1    领域结构的USE CASE表达

USE CASE是描述“类”的名字、类型、属性、责任和它的协作关系的形式化工具,它有表格形式[6]和图形形式[1]。下面给出描述领域结构的USE CASE文本形式范例:

class 领域结构名字 {

结构属性:

结构属性名字 属性类型,属性描述;

<结构属性名字> 属性类型,属性描述;

……

结构责任:

结构方法名字 存取类型,方法描述;

<结构方法名字> 存取类型,方法描述;

……

结构关系:

协作结构名字,协作关系;

……

}

领域结构名字::结构方法名字 {

结构化自然语言描述的处理功能

}

 

4.4.2    定义结构的扩展点

4.4.1节范例中的“< >”记号,表示括号所包含的内容是该领域结构中不确定(意义不明确或有多种选择)的内容,它们可能是某个结构属性,也可能是某个结构方法。在结构定义时不确定的内容称为结构的“扩展点”,“< >”记号称为“扩展点符号”。结构的“扩展点”在结构被设计和实现时仍然保留,成为构件或构架的“扩展点”。构件或构架的“扩展点”将在构件或构架用于某个应用开发时被具体化。

4.4.3    结构化自然语言描述

参见《构件的程序写作规范(QB-CAKL001210)》。

4.4.4    从其它领域获取可复用结构的原则

在领域分析时,优先到已经存在的其它领域获取可复用结构参与建模,是提高领域分析质量、降低领域分析成本的有用途径,即是复用开发的目的。领域结构可以被完全复用,也可以加以修改。

4.4.5    不设计实现的原则

领域建模时不进行以实现为目的的设计。这一原则有利于使领域分析者集中精力于领域对象类关系的提炼。面向对象方法提供了“继承”、“聚合”、“联合”三种机制来建立对象模型。对于一个对象模型有下面的精简导则:

如果某个类A继承了另外的类B(或者多重继承更多的其它类),把它们向上抽象为一个类,并用类A代表这个向上抽象的类;

如果某个类A聚合了另外的类B(或者更多的其它类),把它们向上抽象为一个类,并用类A代表这个向上抽象的类;

经过所有“继承”和“聚合”关系的向上抽象,对象模型是只有“联合”关系(即E-R关系)的模型。

“不设计实现的原则”即在领域建模时不进行“继承”和“聚合”关系的设计。

 

4.4.6    提取本领域的可复用结构的原则

基于领域模型,一组相同或相似的对象类可能用一个公共的领域结构来说明它们的公共部分。注意到这一原则,在领域结构提炼时,建立某些公共的领域结构,有利于可复用构架、构件的设计与实现。

4.4.7    结构的大粒度原则

“结构”是领域中的顶级抽象的可复用构件。它是一个子系统或一个粒度很大的“类”的规格说明,由它可在设计和实现阶段“向下求精”,或通过“继承”和“聚合”扩展得到具体化的构件。

 

4.5    评估领域模型

领域模型的评估主要是领域结构的复杂性评估。推荐用Albrecht复杂度、COCOMO 2.0复杂度或DeMarco复杂度,从功能组成角度评估领域结构的“功能复杂性”。领域结构的复杂性评估,对于预测领域构件的质量和构件开发、复用、测试、维护的工作量和难度有重要意义。参见《计算机软件构件复用属性规范(QB-CAKL010516)》。

4.6    领域分析的产品

领域定义的产品:

l         功能对象集,区分“特有对象子集”和“其它领域对象子集”

l         特有对象子集,区分“可能复用对象子集”和 “可能非复用对象子集”

领域建模的产品:

l         “特有对象类集”和“其它领域对象类集”;在“特有对象类集”内区分“可复用对象类集”和“非复用对象类集”

l         面向对象的E-R关系领域模型或面向功能的领域模型

领域结构的产品:

l         领域结构集,区分“特有领域结构子集”和“其它领域结构子集”

l         特有领域结构子集,区分“可复用领域结构子集”和 “非复用领域结构子集”

领域评估的产品:

l         所有领域结构的功能复杂性评估表

4.7    领域分析的工具

面向对象方法的工具:

l         UML统一建模语言

l         Rational ROSE 2000集成环境

l         USE CASE

l         对象图:静态模型

l         状态图:动态模型

l         对象数据流图:功能模型

面向功能方法的工具:

l         对象数据流图:功能模型

l         数据词典

l         HIPO表

l         结构化自然语言

l         E-R图

5    概要设计

概要设计面向实现从总体上给出可复用构件开发的解决方案。概要设计依据是领域分析的产品(见4.6节)。概要设计参考以下导则进行。

5.1    采用适当的软件方法

根据领域特点,选取适当的软件开发方法,会起到事半功倍的效果。对于“数据强”的领域可选用面向对象方法,对于“功能强”的领域可选用面向功能方法,对于二者都很显著的领域可选用功能主导的混合方法或面向对象方法。

5.1.1    面向对象的方法

使用面向对象方法的工具(见4.7节)进行设计和开发的方法。由于前阶段领域分析的产品是面向对象的,面向对象的软件方法可以直接映射领域分析的结构成为概要设计的规格说明。如果领域分析的结构粒度太大,可以引入“聚合”进行结构化分解成粒度较小的规格说明。

5.1.2    面向功能的方法

使用面向功能方法的工具(见4.7节)进行设计和开发的方法。以领域分析的结构为出发点,利用“聚合”关系表达,对概要设计的规格说明进行“逐步求精”向下分解,形成结构化的程序结构。

5.1.3    功能主导的混合方法

混合使用面向功能方法和面向对象方法的软件开发方法。使用面向功能方法的工具(见4.7节)以领域分析的结构为出发点,利用“聚合”关系表达,对概要设计的规格说明进行“逐步求精”向下分解,形成结构化的程序结构;在结构化的每个程序结构中引用“类”类型定义对象实例,以扩展结构化方法的能力。

5.2    从需求向设计的转换

领域结构是明确领域要“做什么”(领域需求)的形式化说明。由于领域分析不设计实现,所以,从需求向设计的转换是要基于领域结构引入领域实现所必须的程序部件。一般而言,随机事件驱动的应用域(如“事物处理应用”)需要引入人机界面作为主控;有序事件驱动的应用域(如“自动控制应用”)需要引入并发机制作为主控,并发机制选用适当的程序设计语言可以实现。

5.2.1    引入用户界面设计

如果领域模型或领域结构没有给出用户界面的规格说明,这里需要补充用户界面设计。如果已经给出,则直接进行界面设计。用户界面一般应是可视化的图形界面。领域分析的一个结构应有图形界面中的一个对象对应。也就是说,图形界面中的一个对象将驱动概要设计的一个总体程序。用户界面设计应遵循两个原则:一是满足用户友好操作的原则,二是界面设计与开发环境无关的原则。

5.2.2    引入数据存储设计

如果领域模型或领域结构没有给出数据存储的规格说明,这里需要补充数据存储设计。这是可能的。例如,面向对象方法的分析对象模型,尽管可以给出对象类间的数据关系,但并不一定表达出永久存储的数据实体。引入数据存储对象,作为相关的其它对象的数据目标和数据来源,可以简化这些相关对象之间的关系。同时,在概要设计时首先建立完整、一致的数据存储,是从总体上把握系统稳定性的有效措施。

5.2.3    结构化分解和适当的粒度

如果领域结构的粒度太大,有必要进行结构化分解。结构化分解的机制是“聚合”机制。结构化分解应遵循“数据平衡”的原则[6]。“一个函数(或”类“的方法)一个功能”的导则在对于“粒度”控制是适用的。如果某个设计的结构复杂度太高(如McCabe复杂度超过10)、耦合太强、内聚太低,说明有继续向下分解的必要。

5.2.4    只设计可复用构件的原则

尽管领域分析模型和领域结构说明是针对整个领域的全集,但由于可复用开发的目标是开发可复用构件,因此概要设计只在“可复用领域结构子集”内展开。领域分析模型和其它领域结构保持不变,为可复用开发和复用应用开发时参考。

5.2.5    结构化自然语言描述

概要设计给出实现的 “程序总体结构集”。每个 “程序总体结构”是设计的规格说明。规格说明用结构化自然语言描述,参见《构件的程序写作规范(QB-CAKL001210)》。

5.3    构架与构件的设计

每个 “程序总体结构”代表了一个可复用实体,“程序总体结构”下面的某些子项也可能成为可复用实体。构架和构件是两种不同类型的可复用实体,下面是构架和构件结构设计的若干导则:

5.3.1    区分构架与构件的原则

构件(Component)可以不加修改或者基本不加修改地作为一个部件和其它构件一起组装成更大的软件;构架提供应用域的可扩展的模板,具组装其它构件或程序的扩展点。构架(Framework)也是一种构件,可以被组装。构件和构架在程序总体结构中可以互相包含。参见《计算机软件构件复用属性规范(QB-CAKL010516)》。

5.3.2    复用设计的原则

优先到已经存在的其它领域的“程序总体结构集”中获取可复用的设计结构参与设计。

5.3.3    “联合”结构的柔性化

有的 “联合”关系可能造成结构之间的“紧耦合”。“紧耦合”的程序结构不利于程序的调整。某些措施可以使“联合”关系柔性化。例如,“多对多”联合可以用一个“关系表”代替而使原来“联合”的两边与“关系表”成为“一对多”关系;“数据流”关系可以定义为一个共享的数据对象而避免了原来关系的一边作为另一边方法的参数被引用;避免“联合”关系的数据作为控制参数被引用,等等。

 5.3.4    用“继承”与“聚合”扩展结构

领域分析不设计实现,所以领域模型是一个只有“联合”关系的模型。在概要设计中,只要有必要,“程序总体结构”的总体或它的任何子项都可以用“继承”与“聚合”来扩展它的结构。

 

5.3.5    保持领域结构“扩展点”的原则

领域分析的领域结构中需求不确定的部位用“扩展点”Begin-end对表示。这种需求不确定的部位必须在概要设计以及下面的详细设计中被保留,在结构写作时用Begin-end对表示参见《构件的程序写作规范(QB-CAKL001210)》)。

5.3.6    引入新的设计“扩展点”的可能性

概要设计以及下面的详细设计中,有的功能部位,虽然需求是明确的,但针对不同的应用,可能有不同的实现;或者有的功能部位,由于设计结构的柔软性,可能演化为其它功能服务其它应用。这类功能部位都可以定义为“扩展点”用Begin-end对表示

5.3.7    考虑程序段修改的可能性

概要设计以及下面的详细设计中,有的程序段因考虑结构的柔软性,可能在不同的应用时被修改。这类程序段也可以定义为“扩展点”用Begin-end对表示

5.4    概要设计产品

概要设计的产品是领域内可复用构件的“程序总体结构集”,每个“程序总体结构”是一套设计规格说明,包括程序总体结构中每个子项的设计规格说明。

 

5.5    概要设计工具

同领域分析工具,见4.7节。

5.6    概要设计评估

概要设计的产品,根据需要和可能,进行“复用程度”、“结构属性”、“功能复杂性”和“结构复杂性”评估,以考察设计的质量、开发和维护的难易程度。参见《计算机软件构件复用属性规范(QB-CAKL010516)》。

6    详细设计与编码

详细设计根据概要设计的“程序总体结构”进行,产生可以指导或直接导出编码的“程序编码规格说明”。5.7节“构架与构件的设计”所述各项导则也适用于详细设计。除此之外,还有以下导则:

6.1    继承概要设计软件方法的原则

继承概要设计的软件方法是使领域构件开发保持可追踪性的必然途径。不要随意改变软件设计方法。然而,面向功能方法可以随着开发的演化改变成功能主导的混合方法,依然具有同等的可追踪性。

6.2    详细设计与开发环境无关的原则

详细设计必须与程序的编码环境无关,因此详细设计的产品“程序编码规格说明”必须用结构化的自然语言书写。

6.3    程序风格

好的程序必须有完整的说明注释和清楚明了的程序结构表达。说明注释的内容包括程序的名字及其汉语描述、作者及版权申明、程序总体综述、复用构件的名字及其关系说明、属性或变量的名字及其汉语描述、方法或函数的名字及其汉语描述、方法或函数的功能以及关键算法的结构化自然语言描述,等等;程序结构应用结构化语言书写;程序结构内的语句应“嵌套缩近”、错落有;属性或变量、方法或函数的名字避用汉语拼音而用英文单词或开头字母大写的英文单词的组合,缩写要使读者可以辨认,等等。参见《构件的程序写作规范QB-CAKL001210)》。

6.4    接口设计

方法或函数的接口即方法或函数的参数表。以下规定是参数表设计应遵循的原则和保持参数表作为方法或函数唯一的外部接口的准则:

l         标准化,即每个参数的类型、名字有定义,类似方法或函数的参数表在排列上有一致性(例如,同一“类”的多个constructor申明);

l         参数表中的参数定义时赋初值

l         不用参数表中的参数返回方法或函数执行的结果;

l         定义方法或函数的类型,即return返回值及其类型;

l         定义方法或函数的原型;

l         避免使用全局变量;

l         避免在参数表中使用控制变量;

l         避免使用静态变量;

l         不容许方法或函数之间交叉访问;

l         中断子程序的执行必须从中断点启动并在中断点返回。

6.5    程序结构

程序结构可以由多种机制实现,但程序的复杂度应该受到控制,以下是控制结构复杂度的若干导则:

l         程序主体(除开它所复用的构件)的尺度要适中,一般在2页纸左右为好;

l         程序的结构层数不能太多,一般控制在5层以内,最多不要超过7层;

l         避开使用继承类的方法;

l         多重继承的重数不要超过3重;

l         最大继承深度不要超过5层;

l         聚合和联合的对象数一般限制在5以内,最多不要超过9;

l         不要使用静态存取属性(static);

l         少使用保护存取属性(protected);

l         Begin-end对注释,保持概要设计建立的“扩展点”;

l         在结构之外编写方法;

l         设计单入口单出口的方法或函数;

l         一个方法一个功能”;

l         不对运算符重定义;

l         可能被重定义的方法或函数用“虚函数”定义;

l         同样功能的方法或函数不用不同的算法

l         同样功能有不同算法,取其依赖性最小的算法

l         推荐使用“根程序”自顶向下开发,如一个复杂的报表输出,可用cout << “打印雇员工资单”语句作为根程序。

l         结构的“耦合度”要低,“内聚度”要高。

6.6    程序结构评价

详细设计或程序编码的结构复杂度可用McCabe复杂度或Dhama内聚度评价。其它结构因子的评价参见《计算机软件构件复用属性规范(QB-CAKL010516)》及其说明。

6.7    详细设计产品

“程序编码规格说明”和程序。

6.8    详细设计工具

l         《构件的程序写作规范(QB-CAKL001210)》

l         结构化自然语言

l         程序设计语言和环境

7    质量保证和测试

质量保证QA和测试活动有助于开发活动遵循所采用的标准,保证所开发的构件确实是可复用的。

7.1    评价活动

QA的在整个开发周期的跟踪性审查是保证开发各阶段转移不致损失可复用性的重要措施。一个阶段的审查是以上一阶段的产品为依据。对复用而言,领域分析和概要设计的审查尤为重要,不仅要审查产品,也要审查过程,评价本阶段复用标准的有效性。

7.2    度量

度量主要起三个作用:度量构件的可复用性,评估构件的复杂度并预测可能的投入收益,为可复用构件库提供所需信息,如质量、稳定性、复用铝等。《计算机软件构件复用属性规范(QB-CAKL010516)》是度量标准,有的度量可以开发工具实施。度量的收益者不仅是初始项目开发组,更大的收益者是实施复用的整个组织。

7.3    测试过程

测试活动既要保证构件的质量和健壮性,又要保证满足整个项目的复用要求。应该将每个构件作为独立的产品进行比单元测试更家严格的测试。对构件的测试数据和测试案例应该作为构件的组成成分进行管理。对构件的修改应有相应修改的测试数据和测试案例,并要用原来的测试数据和测试案例进行复测,以比较修改后的构件是否满足原来的需求。不要在测试中引入构件本身没有的平台相关性和系统相关性。

8    复用构件文档

构件的文档构成其复用价值的一个关键部分,它除了有通常文档的作用外,还为构件的复用者提供了明确的指导。

8.1    应用传统的文档标准

传统的文档标准是制定复用构件文档的重要参照依据。复用构件文档比之传统文档,最重要的是加进了可复用开发标准、复用应用标准和用评价标准。复用构件文档应该是完备的和自包含的。用户应该易于得到他关心的构件的文档及其所链接的相关文档。不同构件的文档应该相互独立,避免过多的外部依赖和相互参照。

8.2    为复用构件库准备文档和复用者手册

构件及其文档按照《计算机软件构件媒体与分类规范(QB-CAKL010201)》置于构件库JB LIB中,《可复用构件库使用指南(QB-CAKL01/5/30)》是构件复用者可以参照的构件库使用手册。

 

9    最简工程步骤

以上各节给出了可复用构件开发各阶段的详细步骤及其导则。然而,对于某些相对简单的领域构件,并不一定经历上述所有步骤。这里,给出一个最简工程步骤,以供参考。

9.1    领域分析

Step1   确定领域边界

Step2   区分领域内的其它领域边界

Step3   区分领域内的可复用边界

Step4   建立领域模型

Step5   建立领域结构

Step6   复审

9.2    构件设计

Step1   对可复用领域结构进行顶级设计

Step2   结构化向下分解

Step3   “联合”结构的柔性化

Step4   用“继承”和“聚合”扩展结构

Step5   引入“扩展点”

Step6   用结构化自然语言写出“构件设计规格说明”

Step7   复审

9.3    构件实现

Step1   细化“构件设计规格说明”(可省略)

Step2   用程序设计语言或环境编码

Step3   复审和测试

10    附则

本规范由“青鸟生产线技术引进、开发、应用、示范”项目组负责解释并执行。

11    参考文献

[1] Ivar Jacobson, Martin Griss and Patrik Jonsson, Software Reuse: Architecture, Process and Organization for Business Success, Reading, Addison Wesley Longman, NY, 1997.

[2]杨芙清 软件复用及相关技术,计算机科学,26卷5期,pp.1-4,1999

[3] NATO Standard for Development of Reusable Software Components, issued and maintained by NATO Communication and Information System Agency

[4] DeMarco T., Controlling Software Projects, Reading, Yourdon Press, NY, 1982.

[5] 丁志强 《面向应用域的软件复用方法(结题报告)》,云南省应用基础研究基金项目(98F052M).

[6] Roger S. Pressman, Software Engineering: A Practitioner’s Approach, 4th Edition, Reading, the McGraw-Hill Companies, Inc. NY, 1997.

 

 

构件的程序写作规范

作者:云南省计算机应用重点实验室QB-CAKL001210)

 

本规范参照GB 8566-88 《计算机软件开发规范》并具有与《青鸟构件规范》的一致性。

1  目的

本规范为实施《青鸟软件生产线技术的引进、开发、应用和示范工程》而规定程序写作的视角组织、注释要求、标识符起名、扩展点标识等规则。

2  适用范围

本规范适用于计算机软件程序的编写。

3   规范的表达

本规范参考C++语言,分别给出“类”结构的程序型和结构化“函数”程序的型,型中“< >”包括的元素在范型后加以说明。4GL环境下编程,如MFC AppWizard、PowerBuilder的数据窗口等,注释的添加、标识符的起名、Script程序的编写也服从本规范。

 

型采用巴科斯范式(BNF,Backus Normal Form)描述,描述符号意义如下:

::=    定义符,意为“定义为”。

      连选符,符号两边的内容必须选取(可省略,省略时自然连接的内容必须选取)。

|       选择符,符号连接的内容选择其中一个。

[ ]     任选符,符号内用分隔符分隔的内容可选一个、多个,或者不选。

      重复符,符号前任选符包含的内容可以重复一个或多个,或者不重复。

< >         待定义符,符号内的内容需要再定义。

“”        复用定义符,符号内的定义被继承。

 

4    “类”程序

/********************************************************************/

    /*<类名字>,类汉语名字                                              */

    /*作者名,版权所有申明,编写日期                                    */

    /*类属性和功能的综合描述                                            */

    /********************************************************************/

/*

外部说明:

    [<构件名字>,构件汉语名字,引用关系:继承 | 聚合 | 联合 | 数据流;]

   

内部说明:

[<方法名字>,汉语方法名字,<处理的简要描述>]

   

*/

 

class<类名字>[:<存取属性>]<基类名字>,[<存取属性>]<基类名字>,]…]{

[<存取属性>

<类型><属性名字>;                  //汉语属性名字

[ <类型><属性名字>;]                 //汉语属性名字

]

[<存取属性>

<类型><方法名字>[<参数表>]     //汉语方法名字

[ <类型><方法名字>[<参数表>];]        //汉语方法名字

]

/********************************************************************/

    /*<方法名字>,方法汉语名字                                          */

    /*方法处理的综合描述                                                */

    /********************************************************************/

/*

接口参数说明:

    [<类型>,<参数名字>,参数汉语名字;]

   

返回值说明:

    <类型>,[<参数名字>,参数汉语名字],简要说明;

*/

<类型><类名字>::<方法名字>[<参数表>]){

[<程序语句>|<结构化描述语句>]

}]

   

 

5    “函数”程序

/********************************************************************/

    /*<函数名字>,函数汉语名字                                          */

    /*作者名,版权所有申明,编写日期                                    */

    /*函数处理的综合描述                                                */

    /********************************************************************/

/*

外部说明:

    [<构件名字>,构件汉语名字;]

   

接口参数说明:

    [<类型>,<参数名字>,参数汉语名字;]

   

返回值说明:

    <类型>,[<参数名字>,参数汉语名字],简要说明;

*/

<类型> <函数名字>[<参数表>]){

[<程序语句>|<结构化描述语句>]

}

 

6    说明

 

双括号: 〈类名字〉
〈基类名字〉
〈属性名字〉
〈方法名字〉
〈参数名字〉
 

 


::= <首字母大写的单词>+ [<首字母大写的单词>+ …]

 

 

 

名字例:    SalesHistory        //销售履历

                        EmployeeSalary      //雇员月薪

 

<存取属性>::=  public | private | protected | friend

< 类  型 >::=  <C语言类型保留字>|<类名字>

<参 数 表>::=   <类型> <参数名字>[,<类型> <参数名字> …]

 

7    结构化描述语句

 

<结构化描述语句>::= <陈述句>|<IF语句>|<CASE语句>|<WHILE语句>|<UNTIL语句>

 

<陈 述 句>::= [<主语>] +<谓语>+<宾语>[+<宾语补足语>]

                          例:  打印雇员工资表

体重等于70公斤

取雇员工资到工资表

 

<IF 语 句>::= IF< 陈述句>

                        THEN    <结构化描述语句>;

                                [<结构化描述语句>; … ]

                      [ ELSE    <结构化描述语句>;

                            [<结构化描述语句>; … ]]

                    IFEND

 

<CASE语句>::= CASE   

CASE:<陈述句>

    <结构化描述语句>;

                        [<结构化描述语句>; … ]

[ CASE:<陈述句>

          <结构化描述语句>;

                    [<结构化描述语句>; … ]]

                       

                    CASEND

 

<WHILE语句>::= WHILE   <陈述句>

    <结构化描述语句>;

                        [<结构化描述语句>; … ]

                    WHILEND

<UNTIL语句>::=UNTIL   

    <结构化描述语句>;

                        [<结构化描述语句>; … ]

                    UNTILEND <陈述句>

 

8    扩展点

如果程序中有的内容是不确定(意义不明确或有多种选择)的,它们可能是程序中的某个属性或数据项,也可能是程序中的某个方法或函数,这种不确定的内容称为程序的“扩展点”。“扩展点”通常出现在可复用构件体中。构件的“扩展点”将在该构件被应用于某个具体的应用系统开发时具体化。书写“扩展点”时,用下面的注释语句明示:

 

//Begin <扩展点名字>,描述

//用户可扩展部分

//End

 

9    附则

本规范由“青鸟生产线技术引进、开发、应用、示范”项目组负责解释并执行。

 

 

 

 

 

 

 

 

计算机软件构件媒体与分类规范

 

作者:云南省计算机应用重点实验室QB-CAKL010201)

 

 

本规范参照GB 8566-88 《计算机软件开发规范》并具有与《青鸟构件规范》的一致性。

1  目的

本规范为实施《青鸟软件生产线技术的引进、开发、应用和示范工程》而规定构件媒体与分类的方法。

2  适用范围

    本规范适用于电子商贸和办公自动化两个应用域的计算机软件构件的收集、整理与分类。

3  定义

3.1 构件

构件是计算机软件构件的简称,是在软件生命周期各阶段可以重复利用(即“复用”)的软件、程序、原代码模块、目标模块、程序框架、程序段和软件需求说明、规格说明、程序说明、数据说明、测试说明和测试案例等。所谓“重复利用”包括完全复用和修改复用。

3.2 媒体

构件表现的有形载体。本规范特指存储构件的永久性磁介质载体,如光碟、磁盘、软盘。操作系统通过驱动器来读写永久性磁介质载体,驱动器用驱动器名字来标识。

3.3 文件

操作系统文件管理的一个永久性文本或二进制等其它存储类型的数据实体。文件用名字标识并与其它文件区分。

3.4 文件夹

操作系统文件管理的一个用以存储文件的永久性存储空间。文件夹用名字标识并与其它文件夹区分。

3.5 路径

文件存储在文件夹中,一个文件夹可以包含一个或多个下一级的文件夹,文件夹的包含可以有一级或多级。文件夹存储在永久性磁介质载体上。操作系统用驱动器名、文件夹名或者多个文件夹名的级连、文件名,表达了文件的存储位置,这种表达称作文件的路径。

3.6 应用族和应用

应用族是一个应用领域中若干应用的集合。应用指应用计算机、通信等技术为满足用户要求开发的计算机应用系统。本规范特指计算机应用系统中的软件,包括软件的程序和文档。

3.6 分类

根据应用目的建立不同属性的文件夹或分级的文件夹,根据文件的性质把不同的文件放入到不同属性的文件夹中的过程称文件的分类。本规范的“文件”特指构件,“分类”特指构件的分类。

4    分类方法

4.1    第一级(最高级)分类

第一级分类的文件夹有16个,分别定名为:青鸟规范、青鸟工具、Rational Rose、ORBIX、台中央大学规范、QT构件、PHP构件、MYSQL、LINUX、自著文献、EC构件、OA构件、CGI界面构件、DB接口构件、生成式报表构件、其它。

4.1.1    青鸟规范

包括下列MS WORD文件:青鸟构件模型、青鸟构件描述语言JBCDL参考手册、青鸟构件开发指南(V2)、青鸟软件复用过程指南、青鸟领域工程指南、青鸟构件库概念模型、NATO软件复用标准简介。

4.1.2    青鸟工具

下分2个文件夹,分别定名为:青鸟OOA和青鸟RET。

4.1.2.1    青鸟OOA

青鸟面向对象系统分析环境JBOO1.52。

4.1.2.2    青鸟RET

青鸟逆向生成工具Jbpct。

4.1.3    Rational Rose

面向对象建模工具Rose 2000。

4.1.4    Orbix

CORBA平台。

4.1.5    台中央大学规范

台湾中央大学构件文档。包括:系统发展与维护POS分析规格书、书店简易型POS系统构件规格书、书店简易型POS系统细部设计报告、附件1采购进货构件索引、附件2仓库配送索引、附件3销售构件索引、附件4构件登记表。

4.1.6    QT构件,QT编程环境和QT构件源码。

4.1.7    PHP构件,PHP运行环境(Apache、PHP、MySQL)。

4.1.8    LINUX,Linux操作系统及源码。

4.1.9    自著文献,收入本项目成员的个人简介、论文、著作、技术报告、硕士论文等。

4.1.10    其它,OPEN SSL源码等。

4.2    应用族文件夹

本规范规定两个应用族文件夹,即“EC构件”文件夹和“QA构件”文件夹。

4.2.1   EC构件

存放电子商贸领域里的应用。每个应用设文件夹,文件夹按应用名称加反映程序特征的符号定名,如“百姓服务网PB”文件夹、“医药进销存PB”文件夹和“进销存C++BS”。

4.2.2    OA构件

存放办公自动化领域里的应用。每个应用设文件夹,文件夹按应用名称加反映程序特征的符号定名,如“省委系统PB”文件夹、“交通学校LOTUS”和“劳动力市场PHP”文件夹。

4.2.3    应用构件分类

每个应用设一个总的文件夹,下包含一个readme.txt文件和“需求”文件夹、“设计”文件夹、“编码与测试”文件夹、“系统测试”文件夹、“系统使用手册”文件夹、“应用反馈”文件夹、“参考文献”文件夹。

4.2.3.1    readme.txt

汉字文本,说明(1)应用的版本、版权、开发周期、作为构件收录的时间;(2)应用的开发工具、开发环境及其用途;(3)系统安装入口。

4.2.3.2    需求

存放应用项目招标书、项目投标书、用户需求、项目合同、需求分析文档、Rose对象分析文件(即Rose Model,MDL后缀文件)。

4.2.3.3    设计

存放应用项目系统设计、数据库设计、程序设计、算法设计、通信设计文档和Rose对象设计文件(即Rose Model,MDL后缀文件)。

4.2.3.4    编码与测试

每个构件设一个文件夹,文件夹按构件汉语名称加反映程序特征的符号定名,如“信息浏览PB”文件夹、“公文流转LOTUS”文件夹和“购物车C++”文件夹。内容包括源程序、目标程序、可执行程序、测试用例、技术规格说明、构件使用说明。

4.2.3.5    系统测试

为系统测试的每个用例设一个文件夹,文件夹按用例的测试目的起汉语名称定名,如“客户登记表”文件夹、“公文流转”文件夹、“商品目录”文件夹、“价格边界测试”文件夹等。内容包括源测试用例、用例安装、用例使用说明、可预见结果表。

4.2.3.6    系统使用手册

组成应用系统的各软件的使用手册的MS WORD文本。

4.2.3.7    应用反馈

存放用户意见摘编的MS WORD文本。

4.2.3.8    参考文献

存放应用系统开发所引用的参考文献。

4.3    CGI界面构件

存放C++编写的用于Web页面的用户CGI构件,包括界面展示构件和Cawfeecgi的环境参数、界面读取构件。每个构件设一个文件夹,文件夹按使用目的的构件汉语名称定名,如“树型菜单”文件夹、“对象风格”文件夹和“表单”文件夹等。内容包括源程序、测试用例、技术规格说明、构件使用说明。

4.4    DB接口构件

存放C++编写的用于不同数据库存取的接口构件。每个构件设一个文件夹,文件夹按数据库管理系统名称定名,如“Sybase接口”文件夹、“SQL接口”文件夹等。内容包括源程序、测试用例、技术规格说明、构件使用说明。

4.5    生成式报表构件

存放“C++报表程序生成器”构件。内容包括源程序、可执行程序、测试用例、技术规格说明、构件使用说明。还包括由“C++报表程序生成器”产生的栅格报表范本、二维报表范本、自由报表范本文件夹,每个范本文件夹由三个文件组成:报表C++源程序、报表HTML文件和报表数据文本。

5    附则

本规范由“青鸟生产线技术引进、开发、应用、示范”项目组负责解释并执行。

 


可复用构件库设计规范

作者:云南省计算机应用重点实验室QB-CAKL01/5/30

 

构件库浏览页面catalogue.htm

<应用领域>公共领域 | 办公自动化领域 | 电子商贸领域 | 其它领域

        向前 向后 首页 末页

<公共领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<办公自动化领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<电子商贸领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<其它领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

 


查找操作界面

    preface.htm                                                            catalogue.htm

 

 

 

 

 

 

 

 

 

 

 

 

 


                          Read     Keywords         Read                                                                     Seek.exe                         Target.htm      

流程图:预定义过程: 关键字查找

应用领域:公共领域 | 办公自动T

化领域 | 电子商贸领域 | 其它领

                

<公共领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页

……          //按“类型”排序

……          //在“类型”内按构件的英文名字排序

<办公自动化领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页

……          //按“类型”排序:

……          //在“类型”内按构件的英文名字排序

新目录

 
                                         Write & Start

 

 


       构件英文名.htm(构件属性表)  Start form catalogue.htm

 

 

 


                                      tart from target.htm

 

 


                                                     JB_LIB

                                              Download

                                              Start

                                              Start

 

 


                                              Download

                                              Download

 

                                                     构件体x.cpp

                                                     构件复用属性页面构件英文名.htm

                                                     参考文献Y.dbf

 

构件复用属性页面构件英文名.htm

说明属性

构件名字:唯一的英语名字                 汉语名字

构件提供者、联系人、联系方式、提供日期

       版权信息:

              作者名

              版权所有者

              版本号

              出版日期YYYY/MM/DD

              收录日期YYYY/MM/DD

用逗号“,”分隔的本版本前的版本号系列

 
        版本历史

        内容摘要

描述构件的应用领域、构件类型、开发工具、开发方式、运行环境、主要功能和复用程度等

 
 

 

 

 


说明构件的应用领域、类型和重要功能的4个左右的英文词,每个词用逗号隔开

 
        关键字

使用属性

        应用领域:公共○ 办公自动化○ 电子商贸○ 其它○

        构件形式:文档○ 源码○ 二进制码○   文档、源码、二进制集○

               对所提供的构件加以以下说明:

               文档:规格说明□ 设计说明□ 实现说明□ 测试案例□ 使用说明□ 工程书□

                            注:“工程书”是规格说明、设计说明、实现说明、测试案例、使用说明集。

               源码的程序设计语言   

               二进制码:DLL LIB ActiveX CORBA 其它□

                     注:文档、源码、二进制集总称“工程”。

 

 

        构件类型:

               人机界面○ 任务构件○ 数据访问构件○ 数据库接口○ 子系统○ 应用系统○

        开发方式:面向对象○ 结构化○ 混合○  注:“混合” 指结构化套用面向对象混合编程。

说明主要的构件开发工具、开发环境和支持软件

 
        开发工具

说明构件运行必须依赖的操作系统、数据库或网络等

 
        运行环境

        用程度

            ○ 构件的所有代码不加修改的复用

            ○ 构件的操作或代码被修改的量在25%以下

            ○ 构件的操作或代码被修改的量在25%以上

                     新制作的构件

        使用次数           修改次数            

        约束申明

构件不能被使用的约束条件,它们可能是技术的、经济的或法律的约束

 
 

 

 

 


结构属性

       构件结构属性:

        服务数

注:服务数为构件本身和它复用的构件提供服务的方法数,或构件本身和它所复用的构件直接存取外部数据的函数、方法数,或构件本身和它所复用的构件的子系统数和所有子系统“功能点”总数。

        方法/函数            即构件本身和它复用的构件在构件主体中实例化的方法、函数

        结构层数            即构件本身(不包括复用构件)的结构化层次数。

        继承类数            即所有的被构件主体继承的继承“树”的“类”的总和。

        继承重数            即所有的被构件主体继承的继承“树”的根节点数。

        最大继承深度            即所有的继承“树”的从根节点到叶节点的最长路径之

        平均继承深度            即“继承类数”除以“最大继承深度”。

        聚合对象数            即构件主体聚合的“类”的实例数。

        联合对象数            即构件主体的方法或函数在参数表中引用的“类”的实例数。

扩展点数             即构架中提供给用户自定义或自实现的操作或功能数。

        耦合度           即:继承重数×平均继承深度+聚合对象数+联合对象数

低内聚度           低内聚度定义为构件主体的每个方法(或函数)、实例的方法存取属性

变量的“属性变量集”进行“交”运算所形成的不相交集的个数

评价属性

       功能复杂性:

Albrecht复杂度          COCOMO 2.0复杂度          DeMarco复杂度

       结构复杂性:McCabe复杂度            Dhama内聚度

内容属性

       下载构件体 //“下载次数”加1,弹出下载框操作下载

构件关系:

 构件英语名字 汉语名字         连接关系: 继承○ 聚合○ 联合○ 数据流○

 构件英语名字 汉语名字         连接关系: 继承○ 聚合○ 联合○ 数据流○

        ……         //双击启动构件复用属性页

 


说明:

查到某构件时(双击构件英语名字 汉语名字)启动新窗口显示此表(构件英文名.htm)。

此表中所有信息不可修改。

此表中的在构件登记时选中的□或○,在查到显示时涂黑显示为¢˜

构件关系下的“构件英语名字 汉语名字<内容摘要><关键字>”的定义与catalogue.htm完全一致,连接到有关系的构件的“构件复用属性页面”(构件英文名.htm)。双击构件英语名字 汉语名字启动新窗口显示关系构件的“构件复用属性表”。

启动的新窗口,按关闭按扭“T”返回下层窗口。

”是下载图标。


构件复用属性定义页面AttDefine.htm

页面结构和形式除开以下部分均与“构件复用属性页面”相同。

内容属性

       构件体 路径:/C://jb_lib/办公自动化/源码

//双击图标弹出文件浏览器,找到本构件体,把“下载构件体”、路径写到本构件“构件复用属性页面”

//的“下载构件体”位置。如果重复同样过程,新路径覆盖原来写到“构件复用属性页面”的路径。每

//一次过程完,回显路径如上例。

       加入构件关系

        构件英语名字 汉语名字         连接关系: 继承○ 聚合○ 联合○ 数据流○

        构件英语名字 汉语名字         连接关系: 继承○ 聚合○ 联合○ 数据流○

……

//固定格式,共10行。

//双击图标弹出文件浏览器,找到关系构件的“构件复用属性页面”,记下路径,回显关系构件的“构件//英文名字”和“汉语名字”在如上位置;然后在连接关系中选择其一;把关系构件的“构件英文名字”//和“汉语名字”、“路径”、“连接关系: 继承○ 聚合○ 联合○ 数据流○”信息作为一行写到本构件“构//件复用属性页面” 的“构件关系”当前行的下一行位置。如果重复同样过程,新信息覆盖原来写到“构//件复用属性页面”的信息。

 

说明:

此表的所有选择框□或○、文本框、路径符定义的信息均可修改。

在定义过程中任何位置,均可中断;中断前定义信息可以保持。

表的入口:新增一个构件,出空表,输入英文构件名字时,检查是否“重名”;修改一个构件属性时,先进入catalogue.htm,查到要修改的构件的“英文构件名”,依据“英文构件名”读该构件的“构件属性表”(英文构件名.htm)到本“构件属性定义表”,再进行修改。

 

 

 

 

 

 

 

 

 

 

 

可复用构件库构件登录指南

作者:云南省计算机应用重点实验室QB-CAKL01/5/30)

 

       本规范说明“可复用构件登录程序”的使用方法和要求。《计算机软件构件复用属性规范》(QB-CAKL010516)是使用该程序时必须遵照地规范。

1          适用范围

本规范所说明的“可复用构件登录程序”仅允许云南省计算机技术应用重点实验室SE研究室有关人员使用。

2          适用环境和启动

“可复用构件登录程序”运行于Windows环境下的IE 浏览器(Internet Explorer)。在IE浏览器的“地址”栏,发命令http://202.203.240.100/server/editor.htm 即可启动。输入用户名、口令,进入“构件登录页面”。

3          使用规程

构件收录构件库的过程是“提交-测试-验证-批准-登录”。

提交的内容有:

l         需求规格说明(doc文件或Rose文件)

l         设计文档(doc文件和Rose文件)

l         使用说明(doc文件)

l         构件源码(开发环境文件或txt文件)

l         测试案例(doc说明文件和测试环境所需的其它文件)

l         驱动程序源码(开发环境文件或txt文件)

l         构件登录表(纸介质文件或doc文件)

来自第三方的构件可不受上述“提交内容”的限制。

测试:指构件的单元测试和集成测试。来自第三方的构件因条件决定测试方式。

验证:指用驱动程序和测试案例运行构件,评审测试结果。

批准:由SE室主任或他授权的他人批准,并指定构件可登入的文件夹。

登录:首先在服务器的JB LIB打开批准人指定的文件夹,建立即将登入构件的文件夹,复制所有提交文件到该文件夹,然后,在IE环境下启动“可复用构件登录程序”开始登录。

文本框: 注意!构件文件夹的名字必须与构件的英语名字(通常是程序名字)同名。

 

4          程序用户界面

4.1         构件登录页面

构件登录页面构件英文名.htm)

说明属性

构件名字:唯一的英语名字                 汉语名字

构件提供者、联系人、联系方式、提供日期

       版权信息:

              作者名

              版权所有者

              版本号

              出版日期YYYY/MM/DD

              收录日期YYYY/MM/DD

用逗号“,”分隔的本版本前的版本号系列

 
        版本历史

        内容摘要

描述构件的应用领域、构件类型、开发工具、开发方式、运行环境、主要功能和复用程度等

 
 

 

 

 


说明构件的应用领域、类型和重要功能的4个左右的英文词,每个词用逗号隔开

 
        关键字

使用属性

        应用领域:公共○ 办公自动化○ 电子商贸○ 其它○

        构件形式:文档○ 源码○ 二进制码○   文档、源码、二进制集○

对所提供的构件加以以下说明:

              文档:规格说明□ 设计说明□ 实现说明□ 测试案例□ 使用说明□ 工程书□

                            注:“工程书”是规格说明、设计说明、实现说明、测试案例、使用说明集。

              源码的程序设计语言   

              二进制码:DLL LIB ActiveX CORBA 其它□

                     注:文档、源码、二进制集总称“工程”。

        构件类型:

              人机界面○ 任务构件○ 数据访问构件○ 数据库接口○ 子系统○ 应用系统○

        开发方式:面向对象○ 结构化○ 混合○  注:“混合” 指结构化套用面向对象混合编程。

说明主要的构件开发工具、开发环境和支持软件

 
        开发工具

说明构件运行必须依赖的操作系统、数据库或网络等

 
        运行环境

        用程度

                     构件的所有代码不加修改的复用

            ○ 构件的操作或代码被修改的量在25%以下

            ○ 构件的操作或代码被修改的量在25%以上

                     新制作的构件

        使用次数           修改次数            

        约束申明

构件不能被使用的约束条件,它们可能是技术的、经济的或法律的约束

 
 

 

 

 


结构属性

       构件结构属性:

        服务数

注:服务数为构件本身和它复用的构件提供服务的方法数,或构件本身和它所复用的构件直接存取外部数据的函数、方法数,或构件本身和它所复用的构件的子系统数和所有子系统“功能点”总数。

        方法/函数            即构件本身和它复用的构件在构件主体中实例化的方法、函数

        结构层数            即构件本身(不包括复用构件)的结构化层次数。

        继承类数            即所有的被构件主体继承的继承“树”的“类”的总和。

        继承重数            即所有的被构件主体继承的继承“树”的根节点数。

        最大继承深度            即所有的继承“树”的从根节点到叶节点的最长路径之

        平均继承深度            即“继承类数”除以“最大继承深度”。

        聚合对象数            即构件主体聚合的“类”的实例数。

        联合对象数            即构件主体的方法或函数在参数表中引用的“类”的实例数。

        扩展点数             即构架中提供给用户自定义或自实现的操作或功能数。

        耦合度              即:继承重数×平均继承深度+聚合对象数+联合对象数

低内聚度           即定义为构件主体的每个方法(或函数)、实例的方法存取属性(或变量)的

“属性变量集”进行“交”运算所形成的不相交集的个数

评价属性

       功能复杂性:

Albrecht复杂度          COCOMO 2.0复杂度          DeMarco复杂度

       结构复杂性:McCabe复杂度            Dhama内聚度

内容属性


       构件体:

构件关系:

 

 

 

 

 

 

 

 

 

 

 

注:登录构件体或关系构件时,揿浏览按钮,进入文件夹列表,选构件所在文件夹,自动返回并回显该文件夹路径。构件连接其它构件的关系有联合、聚合、继承、数据流等关系。“提交”结束。

 

 

 

4.2             构件浏览页面

构件登录完成后,在IE浏览器的“地址”栏,发命令http://202.203.240.100/server/catalogue.htm,启动构件浏览页面,可在该页面找到该构件的条目。条目内容有构件的英语名字、汉语名字、构件所在文件夹路径、构件内容摘要、关键字。双击构件文件夹路径,进入构件复用属性页面。构件复用属性页面显示格式与前述构件登录页面基本相同。构件体或构件关系的路径,打开相关文件夹,可看到已登录进去的所有构件成分。

 

构件库浏览页面catalogue.htm

<应用领域>公共领域 | 办公自动化领域 | 电子商贸领域 | 其它领域

        向前 向后 首页 末页

<公共领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //连接构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<办公自动化领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<电子商贸领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

<其它领域>人机界面 | 任务构件 | 数据访问构件 | 数据库接口 | 子系统 | 应用系统

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

构件英语名字 汉语名字<内容摘要><关键字> //启动构件复用属性页面

……          //按“类型”排序:人机界面、任务构件、数据访问构件、数据库接口、子系统、应用系统

……          //在“类型”内按构件的英文名字排序

 


附件

构件登记表

填写规则

                   填入文字或数字

                用◎替换,一行内的○只能替换一个

                      ■替换,一行内的□可以替换多个或全部

说明属性

构件名字:唯一的英语名字                 汉语名字

构件提供者、联系人、联系方式、提供日期

       版权信息:

              作者名

              版权所有者

              版本号

              出版日期YYYY/MM/DD

              收录日期YYYY/MM/DD

 

 
        版本历史

        内容摘要

 

 
 

 

 

 


 

 
        关键字

使用属性

        应用领域:公共○ 办公自动化○ 电子商贸○ 其它○

        构件形式:文档○ 源码○ 二进制码○   文档、源码、二进制集○

              对所提供的构件加以以下说明:

              文档:规格说明□ 设计说明□ 实现说明□ 测试案例□ 使用说明□ 工程书□

                            注:“工程书”是规格说明、设计说明、实现说明、测试案例、使用说明集。

                     源码的程序设计语言   

                     二进制码:DLL LIB ActiveX CORBA 其它□

                     注:文档、源码、二进制集总称“工程”。

        构件类型:

              人机界面○ 任务构件○ 数据访问构件○ 数据库接口○ 子系统○ 应用系统○

        开发方式:面向对象○ 结构化○ 混合○  注:“混合” 指结构化套用面向对象混合编程。

 

 
        开发工具

 

 
        运行环境

        用程度

                     构件的所有代码不加修改的复用

            ○ 构件的操作或代码被修改的量在25%以下

            ○ 构件的操作或代码被修改的量在25%以上

                     新制作的构件

        使用次数           修改次数            

        约束申明

 

 
 

 

 

 


结构属性

       构件结构属性:

        服务数

注:服务数为构件本身和它复用的构件提供服务的方法数,或构件本身和它所复用的构件直接存取外部数据的函数、方法数,或构件本身和它所复用的构件的子系统数和所有子系统“功能点”总数。

        方法/函数            即构件本身和它复用的构件在构件主体中实例化的方法、函数

        结构层数            即构件本身(不包括复用构件)的结构化层次数。

        继承类数            即所有的被构件主体继承的继承“树”的“类”的总和。

        继承重数            即所有的被构件主体继承的继承“树”的根节点数。

        最大继承深度            即所有的继承“树”的从根节点到叶节点的最长路径之

        平均继承深度            即“继承类数”除以“最大继承深度”。

        聚合对象数            即构件主体聚合的“类”的实例数。

        联合对象数            即构件主体的方法或函数在参数表中引用的“类”的实例数。

扩展点数             即构架中提供给用户自定义或自实现的操作或功能数。

        耦合度           即:继承重数×平均继承深度+聚合对象数+联合对象数

低内聚度           即定义为构件主体的每个方法(或函数)、实例的方法存取属性(或变量)的

“属性变量集”进行“交”运算所形成的不相交集的个数

评价属性

       功能复杂性:

Albrecht复杂度          COCOMO 2.0复杂度          DeMarco复杂度

       结构复杂性:McCabe复杂度            Dhama内聚度

构件关系(在后填构件英语名字和汉语名字)

                                  连接关系: 继承○ 聚合○ 联合○ 数据流○

                                  连接关系: 继承○ 聚合○ 联合○ 数据流○

                                  连接关系: 继承○ 聚合○ 联合○ 数据流○

                                  连接关系: 继承○ 聚合○ 联合○ 数据流○

                                   连接关系: 继承○ 聚合○ 联合○ 数据流○

                                   连接关系: 继承○ 聚合○ 联合○ 数据流○

                                          连接关系: 继承○ 聚合○ 联合○ 数据流○

                                   连接关系: 继承○ 聚合○ 联合○ 数据流○

                                          连接关系: 继承○ 聚合○ 联合○ 数据流○

                                          连接关系: 继承○ 聚合○ 联合○ 数据流○

 

 

 

 

 

CGI接口和数据库接口参考手册

作者:云南省计算机应用重点实验室

 

一、CGI接口

 

设计

CGI产生基于应用处理的变量在Html页面中的标签产生与应用系统相关的Web界面。这是大多数Web开发环境都使用的机制,也是我们设计人机界应用的机制。但是,直接写标签的CGI程序是比较烦琐的工作。我们根据一般应用要求,抽取一些复杂的大粒度构件设计C++的CGI生成程序,如表单、菜单、树形菜单和页面风格控制等。为保持界面构件的完整性,也开发了若干小粒度的CGI构件。

把每个Html标签作为一个类,都包含 generate方法,通过设置类属性,调用generate方法完成该标签的Html格式化输出,结果放入结果类HtmlResult中。每个标签包含一个CSSstyle对象,来实现标签的显示的风格设定。标签类中可根据需要引用其它或自身的标签类,实现嵌套使用。设计使用了含纯虚函数的抽象类HtmlVirtualObject使每一个界面构件都复用了CSSstyle和HtmlResult。图1和图2表达了设计思想和设计本身。

1 人机界面构件总体规范类图

2 人机界面构件总设计类图

 

CGI界面构件接口和参数

 

htmlhead              html

属性:

title                //标题

方法:

htmlhead (char* title)

 

htmlbuttom          html的结尾

方法:

htmlbuttom ()

 

Form                    表单

属性:

name              //标签名

method           //方法,值选post | get | head

action             //提交的处理文件

target             //指定显示的窗口

enctype          //如何对数据进行编码,只有在post方法使用

       方法:

Form (char* name, char* method, char* action, char* entype, char* target)

AddElement (HtmlVirtualObject *tag)

 

Input                    表单输入域

属性:

              type               //类型,选radio|checkbox|reset|submit|button|password|text|image|hidden

              name              //输入域名

              value              //输入域的值

              size                //输入域大小(该属性并不是所有类型都有)

方法:

          Input (char* type, char* name, char* value, char* size)

Input (char* type, char* name, char* value)      

 

TextArea                     文本输入域

属性:

name              //文本输入域名

rows                     //输入域的行数

cols               //输入域的列数

contentText    //输入域的初始值

方法:

TextArea (name, rows, cols, contentText)

TextArea (name)

 

Select                          下拉列表

参数:

name              //下拉列表名

option            //下拉列表子项

Size                //下拉列表的项数

方法:

Select (char *name)

adoption (char *option)         //加入下拉列表子项到列表中     option

 

frameset                     框架

属性:   

src                //定义框架的URL

name             //定义框架的目标名

rows                    //每一个框架在屏幕上分配的总行数(像素宽度或百分比的集合)

cols               //每一个框架在屏幕上分配的总列数(像素宽度或百分比的集合)

marginwidth   //定义框架的边缘宽度(以像素计)

marginhight    //定义框架的边缘高度(以像素计)

scrolling         //打开或关闭滚动条, YES,NO,AUTO :

noresize         //固定框架大小使用户不能调节, noresize :

frameborder   //框架边框打开选1| yes,关闭选0 | noMicrosoft01),Netscape yesno)。

framespacing  //定义框架之间的空间。Microsoft

方法:

frameset(char* frameborder, char* framespacing)

setFrame(char*src, char*name, char* rows, char*cols, char*marginwidth,

char* marginhight, char* scrolling, char* noresize)

setFrame(char*src, char*name, char* rows, char*cols)

setFrame(char*src, char*name)

 

iframe           内嵌框架

属性:

              src                 //框架的URL

              name              //框架名

align               //对齐,选LEFT | CENTER | RIGHT | TOP | BOTTOM

              width             //浮动框架的宽度

              height             //浮动框架的高度

              scrolling         //打开或关闭滚动条,选YES | NO | AUTO

noresize          //固定框架大小使用户不能调节

frameboder     //框架边框,选0 关闭|,选 1 打开Microsoft

 

方法:

iframe(src, name, align, width, height, scrolling, noresize, frameboder )

iframe(src, name)

 

Link                     链接

       属性:

              name              //链接名

              src                 //连接的URL

       方法:

              link(char* name, char* src)

 

image            图像

属性:

name             //图像映射的名字

src                //URL指定的图像

alt                  //为非图形浏览器的显示提供的替换文本

align                     //将图像与其周围文本对齐方式

height            //设置图像的高度

width             //设置图像的宽度

vwidth           //图像上下和文本周围的空间大小

hwidth           //图像与其周围文本之间的空间大小

border            //给图像加边框,其数值越大,边框越粗

lowsrc           //为最初装载该图像指定一个具有较低分辨率的版本

方法:

Image(char* src);

Image(char* name,char* src);

Image(char* name,char* src,char* alt);

Image(char* name,char* src,char* alt,char* align);

Image(char* name,char* src,char* alt,char* align,int width,int height);

Image(char* name,char* src,char* alt,char* align,int width,int height,

int vwidth,int hwidth);

Image(char* name,char* src,char* alt,char* align,int width,

int height,int vwidth,int hwidth,char* lowsrc);

 

Table                    表格

属性

col                 //表的列数

row               //表的行数

rowspan         //行扩展数,默认1

colspan          //列扩展数,默认1

 

方法:

Table(int row,int col)     //构造器,rowcol为表的行数和列数。

              setRowSpan(int row,int col,int rowspan)

                                                 //设置单元格(row,col)的行扩展数,必须大于1

              setColSpan(int row,int col,int colspan)

                                                 //设置单元格(row,col)的列扩展数,必须大于1

              setWidth(int w)             //用百分度设置表的宽度

              setWidthpx(int w)          //用象素设置表的宽度

              setGridTag(int row,int col,HtmlVirtualObject *tag)

                                                 //设置单元格(row,col)上的html标签类

              setName(char *name)    //设置表的名称

              setBorder(int b)             //设置表的边界线宽度

setCellPadding(int p)      //设置表的单元内容和边界线距离

              setCellSpacing(int s)      //设置表的单元边界线宽度

setHeightpx(int h)          //设置表的单元高度,以象素为单位

              setHeight(int h)             //按百分度设置表的单元高度

setAlign(char *a)           //设置表在界面中的水平位置,参考值left(

//),right(居右),center(居中)

              setBackground(char *url)      //设置表的单元背景图象,如http://127.0.0.1/1.jpg

setBgColor(char *c)             //设置表的背景色,如#ff00ff

              setRules(char *r)                  //设置表的网格线的规则设置

//参考值all,none,cols,rows,groups

setTitle(char *t)                   //设置表的标题

              setFrame(char *frame)         //设置网格属性,参考值voidabovebelowhsideslhs

//rhsvsidesboxborder

setCellCss(int row,int col,CSSstyle *c)

//设置网格的CSSstyle属性。

 

font               字体

属性:

ContentText                         //显示的文本

方法:

  font(char* ContentText)       //构造方法

  setFontColor()                     //设置字体颜色

  setFontFace()               //设置字体类型

  setFontSize()                //设置字体尺寸

  setBackColor()                     //设置背景颜色

这一标签并不是所有的浏览器都支持,主要是微软的一个字体属性设置标签。这一构件所具有的功能大多都可通过调用页面风格设定构件来实现,所以这一构件是可以不要的,但在我们前期研究时,做开发实例时做了该构件,所以这里我们仍将它包含进来了,作为用户的可选构件保留。

TreeStore            树结构存储的类

树结构存储类,不继承抽象类HtmlVirtualObject     

属性:

              treeproperties         //树节点信息类

              Errcode                 //错误码

              Rrtext                   //出错文本

       方法:

createPop(treeproperties* p)                       //返回句柄TreeNodeStr创建顶级菜单

createPop(TREEHANDLE ihandle,treeproperties* p)  

//返回句柄TreeNodeStr创建下级顶级菜单

createItem(treeproperties* p)                      //创建顶级子菜单

createItem(TREEHANDLE ihandle,treeproperties* p)

//创建下级子菜单

createSeperator(TREEHANDLE ihandle)      //创建分隔符

 

TreeProperties          树节点信息类

属性:

nodetype               //树节点类型,选top, pop, sub, sep

text                       //树节点显示的文本

image1                  //节点图像

image2                  //节点图像

link                       //节点的超链接

target                    //指定链接所打开的页面的位置

others                   //其它选项

imagestate             //图像显示状态

width                    //节点文本高度

ltag                       //节点的标签属性

方法:

treeproperties()

treeproperties(char*)

treeproperties(char*,int)

treeproperties(char*,char*)

treeproperties(char*,HtmlVirtualObject *)

treeproperties(char*,char*,int)

treeproperties(char*,char*,char*)

treeproperties(char*,char*,char*,char*)

treeproperties(char*,char*,char*,char*,int)

treeproperties(char*,char*,char*,char*,int,char*)

~treeproperties()

 

 

treeview               树形菜单

属性:

treeStore               //树存储结构

int errcode             //出错返回码

errtext                   //出错返回文本

treeHight               //树节点间的高度

int fontSize            //树的所有字体的大小

方法:

treeview(TreeStore)       //构造函数

3.57            5 整个界面构件设计的总类图

 

menu            菜单

属性:   

treeStore                      //树存储结构对象实例

errcode                        //出错的错误码

errtext                          //出错文本

fontSize                        //定义整个菜单的字体大小

menuHight                    //定义各菜单项的显示高度

menuBGColor               //定义菜单的背景颜色

方法:

menu(TreeStore)           //构造函数

~menu()

 

KeyManager        键值管理器

属性:

keynum                               //键值数目

       key                                     // KeyStr结构体 key-value存储块

方法:   

KeyManager()                                    //构造器

       getKeyValue(char *key,char *value)      //根据key 获取value

       setKeyValue(char *key,char *value)      //设置key-value

 

CSSStyle                     CSS风格定义构件

       继承了类KeyManager

属性:

outbuf                   //输出缓存,存放css风格定义内容

       方法:

              setFontStyle(char *value)                    //normal | italic | oblique

              setBackgroundColor(char *value)         //背景设置

              setColor(char* value)                          //颜色设置,如#ff00ff

              setFontSize(char *value)                            //字体尺寸设置,选xx-small | x-small | small |

//medium | large | x-large | xx-large

              setFontSize(int px)                             //字体尺寸设置(象素)

              setFontVariant(char *value)                 //normal | small-caps

              setFontFamily(char *value)                 //serif | sans-serif | cursive | fantasy | monospace

              setFontWeight(char *value)                 //normalbold

              setBackgroundImage(char *url)           //背景图像

              setBackgroundRepeat(char *value)       //repeat | repeat-x | repeat-y | no-repeat

              setBackgroundAttachment(char *value)              //fixed | scroll 

              setBackGroundPosition(int x,int y)       //单位px

              setBehavior(char *value)                    

                     setBorderBottomStyle(char *value)       //none | solid | double | groove | ridge | inset |outset

setBorderRightStyle(char *value)         //none | solid | double | groove, ridge, inset, //outset

              setBorderLeftStyle(char *value)           //none | solid | double | groove | ridge | inset |outset

              setBorderTopStyle(char *value)           //none | solid | double | groove | ridge | inset |outset

              setBorderLeftColor(char *value)  

              setBorderTopColor(char *value)   

              setBorderRightColor(char *value) 

              setBorderBottomColor(char *value)     

              setBorderColor(char *value) 

setBorderBottom(int px)

setBorderTop(int px)     

setBorderLeft(int px)    

setBorderRight(int px)          

              setBorderBottom(char *value)              //thin | medium | thick

              setBorderRight(char *value)                //thin,medium,thick

              setBorderTop(char *value)                  // thin | medium | thick

              setBorderLeft(char *value)                  // thin | medium | thick

              setBorderWidth(char *value)                // thin | medium | thick

              setBorderWidth(int px)                        //单位px

              setBottom(int px)                               //单位px

              setTop(int px)              

              setLeft(int px)

              setRight(int px)     

              setClear(char *value)                          //one | left | right | both

              setCursor(char *value)                        //auto | crosshair | default | hand | move | e-resize

// | ne-resize | nw-resize | n-resize | se-resize

// | sw-resize | s-resize | w-resize | text | wait

              setDisplay(char *value)                       //none | block | inline | list-item

              setFilter(char *value)                  

              setHeight(int px);

              setWidth(int px);

              setLayoutGridChar(int px)           

              setLayoutGridLine(int px)            

              setLetterSpacing(int px)              

              setLineHeight(int linenum);

              setLineHeightpx(int px);

              setListStylePosition(char *value)          // inside | outside

              setMarginBottom(int px)

              setMarginTop(int px)    

              setMarginRight(int px)  

              setMarginLeft(int px)    

              setOverFlow(char *value)                   //scroll | hidden | visible | auto

              setRubyAlign(char *value)

              setTextAlign(char *value)

              setTextDecoration(char *value)            //none | line-through | underline | overline | blink

              setTextIndent(int px);

              setTextTransform(char *value)            //none | lowcase | uppercase | capitalize

              setVerticalAlign(char *value)    //sub | super | top | text-top | middle | bottom | text-bottom

              setVisibility(char *value)               //visible | hidden | inherit

              setWordSpacing(int px) 

              setZIndex(int z)     

              setPaddingBottom(int px)     

              setPaddingTop(int px)   

              setPaddingRight(int px) 

              setPaddingLeft(int px)   

              cssGenerate()

              CSSstyle()     



部分CGI人机界面构件的McCabe复杂度如下表。

 

构件名

Form

Input

TextArea

Select

McCabe复杂度

26

14

14

15

循环数

2

2

2

2

最大子程序iv

7

4

4

4

 

构件名

Frameset

iframe

Link

image

McCabe复杂度

29

23

8

24

循环数

2

2

3

2

最大子程序iv

9

6

4

6

 

构件名

Table

Treeview

menu

CSSStyle

McCabe复杂度

83

39

53

86

循环数

13

7

7

2

最大子程序iv

6

9

9

6

 

构件名

HtmlResult

KeyManager

Treeproperties

TreeStore

McCabe复杂度

12

29

13

28

循环数

4

2

0

9

最大子程序iv

4

6

2

4

 


二、数据库接口

设计

 

3 数据库接口构件设计

 

建立抽象类DBComponent,有纯虚函数SQLExe()用来执行SQL语句,纯虚函数TranSqlExe()用来执行数据库系统命令。两个数据库接口类SybaseSQL和SQLserver继承抽象类DBComponent,也就继承了它的函数SQLExe()和TranSqlExe(),也可以对纯虚函数重定义。对Sybase和SQL Server,二者有很强共性。执行的结果放入sqlret对象。

 

 

 

 

 

 

 

 

 

 

 

4是Sybase数据库接口的另一种设计,没有用抽象类。

4 不继承抽象类的Sybase接口

 

数据库构件接口和参数

 

DBComponent         抽象类

属性:

conn_ptr               //结构DBPROCESS,来用存储用户的数据库连结信息

login_ptr                //登陆结构体,记录了该应用某次访问的登录用户名、口令、

//服务器名、应用名称等重要信息

rowbuff                //存放执行select语句所返回的纪录值的临时缓存

rownum                //执行select语句所返回的记录数,其他返回0

       colnum                  //执行select语句所返回的列数,其他返回0

afrow                    //执行sql语句后,所影响的行数,select语句返回-1

sqlcode                 //大于0表示sql语句执行成功

sqlerr                    //执行sql语句错误后的出错信息

colname                //返回执行select语句后的列名

       方法:

Virtual SqlExe(char* sqlcmd, SqlRet &sret)        //SQL语句封装函数

Virtual TranSqlExe(char* sqlcmd, SqlRet &sret)  //事务处理

 

               

Sqlret           结果类

属性:

errtext                   //错误文本

                     errcode                 //错误属性码,值:0—表示成功,-1—失败,-2—此行列不存在

              方法:

SqlRet()

~SqlRet()

GetRow()                     //得到行数

GetCol()                //得到列数

GetItem(int row,int col,char *item)            

//获取SQL语句的返回值(仅仅当目标是字符串时使用)

GetItem(int row,int col,char *item,int &itemlen)

//获取SQL语句的返回值(当目标是二进制流时使用)

SetItem(int row,int col,char *item)

                                   //设置表的行列值(仅仅当目标是字符串时使用)

SetItem(int row,int col,char *item,int itemlen)

                            //设置表的行列值(仅仅当目标是二进制流时使用)  

 

SybaseSQL                  Sybase数据库接口

继承了类DBComponent,也继承了它的纯虚方法SQLExe()TranSQLExe(),具有和其父类一样的输入输出参数。同时它通过其构造方法来实现对数据库的连结。

参数:

servername            //服务器名

                     username               //登陆数据库服务器的用户名

                     password                     //口令

                     datebasename         //要操作的数据库名

方法:   

SybaseSQL(char* servername,char *username,char* password,char * datebasename);

 

SQLServer                  SQLServer数据库接口

继承了类DBComponent,也继承了它的纯虚方法SQLExe()TranSQLExe(),具有和其父类一样的输入输出参数。同时它通过其构造方法来实现对数据库的连结。

参数:

servername            //服务器名

                     username               //登陆数据库服务器的用户名

                     password                     //口令

                     datebasename         //要操作的数据库名

方法:

       SQLServer(char* servername,char *username,char* password,char * datebasename);


SQLServer与Sybase数据库的接口构件实现的区别

所需的头文件不同

Sybase: sybfront.h sybdb.h

SQLServer: windows.h sqlfront.h sqldb.h

所需的库文件不同

Sybase: LIBBLK.LIB LIBCOMN.LIB LIBCS.LIB LIBCT.LIB LIBSYBDB.LIB

        SQLServer: Ntwdblib.lib

McCabe复杂度

构件名

SybaseSQL

SQLServer

SqlRet

McCabe复杂度

22

22

39

循环数

8

8

8