- 1 -
中国科技论文在线
基于构件的软件包依赖性度量研究#
唐光义1,王洪峰2,姚登举1*
基金项目:黑龙江省自然科学基金项目()
作者简介:唐光义(1980-),男,讲师,主要研究方向:软件工程、分布式系统
(1. 哈尔滨理工大学 软件学院 哈尔滨 150080;
2. 周口师范学院 计算机科学系 周口 466001) 5
摘要:主要针对系统开发中软件包之间的依赖性进行了分析,提出了软件包的依赖性、稳定
性、无责任性以及系统的稳定性,并设计了检测软件包中是否存在依赖环的算法,最后给出
了软件包设计的原则。
关键词:软件工程;构件;依赖性;依赖环
中图分类号:TP311 10
Research on Measurement of Software package dependency
Based on Component
Tang Guangyi1, Wang Hongfeng2, Yao Dengju1
(1. School of Software, Harbin University Of Science And Technology,Haerbin,150080; 15
2. Department of Computer Science, Zhoukou Normal University, Zhoukou,466001)
Abstract: This paper analyzed the dependency between the software packags,and gived
dependency,stability,irresponsibility and stability of the System,and then designed the algorithm
for detection existence of the package dependency cycle, and finally pointed out that the package
design principles. 20
Key words: Software Engineering; Component; dependency; dependency cycle
0 引言
通常情况下,应用软件的开发一般从需求分析开始,经过设计,编码,测试,最后交付
使用。如果每个应用系统的开发都是从头开始,则在系统开发过程中就必然存在大量的重复25
劳动,如:用户需求获取的重复、需求分析和系统设计的重复、程序编码的重复、测试的重
复和文档工作的重复等。软件复用本质上是运用现存软件系统的产品或工程知识构造新的软
件系统,在软件开发中避免重复劳动[1]。其出发点是应用系统的开发不再采用一切“从零开
始”的模式,而是以已有的工作为基础,充分利用过去应用系统开发中积累的知识和经验,
如:需求分析结果、设计方案、源代码、测试计划及测试案例等,从而将开发的重点集中于30
应用的特有构成成分。
随着企业信息化的发展,各行各业对软件的需求日益提高,软件也日趋复杂,信息管理
系统是各企业根据自己行业领域要求所使用的各类管理系统[2]。第一步,经过充分的分析,
提取信息管理系统的若干通用点,并设计成构件。第二步,提取出所要创建框架的扩展点,
并封装为独立的程序集;如工作流管理、警示管理、系统管理、安全管理、系统设定、个性35
化管理等几个模块是各类信息管理系统的通用点,可以将这些模块封装成构件,插入框架中。
第三,对于特定行业领域的软件产品的开发,开发人员只需要了解业务上的逻辑,然后根据
系统提供的配置信息动态加载实际需要的程序集,并调用其中的提供的方法和属性,实现各
自特定的服务功能。
- 2 -
中国科技论文在线
软件构件模型是关于开发可重用软件构件和构件之间相互通信的一组标准描述。通过重40
用已有的软构件,使用构件对象模型的软件开发者可以像搭积木一样快速构造应用程序。这
样不仅可以节省时间和经费,提高工作效率,而且可以产生更加规范、更加可靠的应用软件。
但是,现在国内外关于软件包之间的依赖性的研究还是比较少的,也没有给出系统的方法来
度量软件包之间的依赖性。
1 软件包依赖性的影响 45
随着应用程序规模和复杂度的增加,需要在更高层次上对它进行组织。类对于小型应用
程序来说是非常方便的组织单元,但是对于大型应用程序来说,如果仅仅使用类作为惟一的
组织单元,就会显得粒度过细。因此,就需要比类“大”的“东西”来辅助大型应用程序的
组织[3]。这个“东西”就是包(package)。一个类经常会和其他类之间存在依赖关系,这些
依赖关系还经常会跨越包的边界,因此,包之间也会产生依赖关系。包之间的依赖关系展现50
了应用程序的高层次组织结构,所以应该对这些关系进行管理。
要对包进行发布,首先要先设计好包,对规模较大的应用来说,划分包的组合很多,仅
仅把看起来像是适合在一起的类放进相同的包中,得到的往往是一种不好的包结构而且会出
现发布很困难、不容易重用、难于更改等问题,这种包结构有可能带来更多的麻烦。显然需
要一些原则来指导包的划分,这些原则用来处理包之间的关系,也是衡量分包合理程度的依55
据。
在软件包的发布中我们有效避免晨后综合症的发生,提高软件包的稳定性、降低软件包
之间的依赖性[4]。造成晨后综合症的原因在于依赖者所依赖的包是变化的,这就使依赖者工
作于一个不稳定的基础之上,对被依赖者的改变,依赖者必须做出相容的改变。采用包的发
布机制,依赖者必须选择被依赖包发布的一个特定版本,而发布后的包,其内容是不允许变60
化的,因此依赖者所依赖的东西就不会改变;同时,被依赖包的任何改变都必须作为一个新
版本发布,而依赖者有权决定是否采用这个新版本,换句话说,是否接受被依赖者的改变是
由依赖者决定的。
图 1 软件包的依赖关系图 65
如果一个新需求迫使需要更改 MyDialogs 中的一个类去使用 MyApplication 中的一个
类。这就产生了一个依赖关系环,这个依赖关系环会导致一些直接后果。例如,工作于
MyTasks 包的开发人员知道,为了发布 MyTasks 包,他们必须得兼容 Tasks、MyDialogs、
Database 以及 Windows 包。然而,由于依赖关系环的存在,他们现在必须也要兼容
MyApplication、 TaskWindow 以及 MessageWindow 包,也就是说,现在 MyTasks 依赖于系70
- 3 -
中国科技论文在线
统中所有其他的包。这就致使 MyTasks 包难以发布。MyDialogs 有着同样的问题。事实上,
该依赖关系环会迫使 MyApplication, MyTasks 以及 MyDialogs 包总是同时发布。它们实际
上已经变成了同一个大包。于是,在这些包上工作的所有开发人员就会再次遭受晨后综合症。
他们彼此之间的发布行动要完全一致,因为他们必须都要使用彼此间完全相同的版本。
2 软件包依赖性的度量方法 75
软件包依赖性的定义
定义 1 依赖性 如果在软件包 P1(C1,C2,……Cn)与软件包 P2(C1,C2,……Cn) 中
))()(())()(( 1221 jiji cpcpcpcp →∃→∃ 或者 ,则称软件包 P1和软件包 P2具有依赖关系,
若 ))()(( 21 ji cpcp →∃ ,则称 P1 依赖 P2 ,若 ))()(( 12 ji cpcp →∃ ,则称 P2 依赖 P1,若
))()(())()(( 1221 jiji cpcpcpcp →∃→∃ 并且 ,则称 P1循环依赖 P2,或者 P2循环依赖 P1。 80
其中,P1 P2表示软件包,C1,C2,……Cn表示软件包中的类,箭头表示软件包中的类的耦
合关系。
如果一个包中的类都是一些基本类,没有继承其他的类,或者它们在开发中,继承的是
系统开发环境中提供的基本类,那么这些软件包是稳定的。例如:在 vc++的开发中,继承
的是 MFC 中的类,在 java 的开发环境中, 中的类等。 85
定 义 2 依 赖 环 在 系 统 开 发 的 软 件 包 P1,P2,P3 … … Pn 中 , 如 果
),( ijji pppp ……→→∃ ,则称在软件包 P1,P2,P3……Pn中存在依赖环。
如果在系统开发的软件包中存在依赖环,那么系统的稳定性和可扩展性都会面临很大的
问题,同时会不可避免的产生晨后综合症。
软件包依赖环的检测 90
判定系统的软件包中是否存在依赖环,可以转换为线性代数中的矩阵运算。设软件包
的依赖关系图 G的邻接矩阵是 A,则 G不含环当且仅当 A,A2,A3,……,An这 n 个矩阵的对
角元素都是 0。例如,对于图 1的依赖关系,我们可以用如下的邻接矩阵表示。
95
A=
100
证明如下:
设依赖关系图 G 是有向图,A 是图 G 的邻接矩阵,A 的第(i, j)个元素 a(i, j)是
vi到 vj的长度为 1的链的个数;
A2的第(i, j)个元素;
a2(i, j) = a(1, i) * a(i, 1) + a(2, i) * a(i, 2) + … + a(n, i) * 105
a(i, n);
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎦
⎤
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎣
⎡
00
00
00
00
10
10
00
00
00
00
01
10
11
01
00
10
11
00
10
11
00
00
01
01
00
00
01
00
00
11
01
10
- 4 -
中国科技论文在线
显然,vi到 vj的每一条长度为 2的链看成两条长度为 1的链相连,所以共有;
a(1, i) * a(i, 1) + a(2, i) * a(i, 2) + … + a(n, i) * a(i, n)条,
就是 a2(i, j);
同理可证,ak(i, j)表示 vi到 vj的长度为 k的链的个数; 110
特别地令 i = j ;
ak(i, i)就是通过 vi的长为 k的环的个数;
显然,若有 n个顶点图 G存在一个环,则必存在一个长度不超过 n的环,因此,G不含
环当且仅当 A,A2,A3,…,An这 n 个矩阵的对角元素都是 0。
通过证明也可以得出,若矩阵 An的对角线元素不都是 0,则说明矩阵 A中一定存在长度115
为 n的环路。并且,这些环路包含了对角线中不为 0的元素。
例如,对于图 1的邻接矩阵 A,则说明在图 1中存在一个依赖环。
A2 =
120
鉴于此,可以设计检测环路的算法如下:
boolean ifexistcircle(A[n][n]){
Int M[n][n],C1[n],C2[n];
int i=0;
while(i<n){ 125
M=M*A;
if(M 对角线元素不全为 0){
将 M 对角线中非零元素保存到 C1 中;
break;
} 130
i++;
}
遍历 A中属于 C1 的元素,并将所有长度为 i的环路保存到 C2 中;
if(C2 为空)
return true; 135
else
return false;
}
对返回的集合进行判断,如果为空说明图中没有环路;如果不为空,则说明图中存在环
路,可以遍历集合,对环路进行处理。 140
软件包依赖环的消除
如果在软件包 P1,P2,……Pn中,存在如下的依赖环 ittjji pppppp →→→ ,, ,可用
如下的图 2表示。
145
⎥⎦
⎤⎢⎣
⎡
…………
……3
- 5 -
中国科技论文在线
150
图 2 软件包的依赖环
假设 )()(),()(),()( iijjttjjjjii cpcpcpcpcpcp →→→ ,则在软件包 ip 中增加一
个新的接口类 ΔC ,令: )()( Δ→ Cpcp iii , )( jj cp 实现接口类 )( ΔCpi 。这时,它们的依155
赖关系可以用如下的图 3表示:
160
图 3 依赖环的消除
此时就可以消除其中存在的依赖环,另外一种比较简单的方法是增加一个额外的软件
包,把它们共同依赖的类放在这个新的软件包中,让它们依赖于这个新建的软件包。 165
3 软件包设计的原则
在系统的开发中,绝对的稳定是不存在的,稳定都是相对的[5]。软件包可以依赖于系统
开发环境所提供的软件包,而系统的开发环境所提供的软件包是稳定,即在相当长的一段时
间内,是不会发生变化的,自己开发的软件包所依赖的基础是固定的,那么系统也就是稳定
的。如果在系统的开发中存在依赖环,那么依赖环中的任何一个包中的类发生变化,都会影170
响到依赖环中其他的包,而且会发生一个连锁反应,对系统的维护和系统的扩展都会带来极
为严重的后果。因此在软件包的设计当中应遵循如下设计原则:
(1)无环依赖原则,在软件包的设计中,不能存在依赖环,否则系统是难以维护的。
(2)包的稳定性原则,在包的依赖关系中,最底层的包一定要是稳定的。
(3)软件包的无责任原则,即对于需要经常变化的软件包,应放置在顶层,不应有其他175
的软件包依赖于它。
4 结束语
在基于构件的开发中,软件包的设计对于系统的开发成功,具有至关重要的作用,因此
在软件包的设计上,要先对软件包的依赖性进行分析,划分出稳定的包和无责任的包,从而
构造出一个稳定的系统。 180
[参考文献] (References)
Pi Pj
Pt
C △
Pi Pj
Pt
- 6 -
中国科技论文在线
[1] 周天琳,徐宝文,史亮等. 基于客户程序度量包内聚性(英文)[J].软件学报, 2009(02):45-51
[2] 杨亚东 ,吴成柯 ,肖嵩等 .提供服务质量保障的图像快速混合丢包保护方法 [J]. 计算机研究与发
展,2006(12):126-131
[3] 王晓博,王欢,刘超.UML 类图层次化自动布图算法[J].软件学报,2009(06):234-245 185
[4] 梅宏,谢涛,袁望洪等. 青鸟构件库的构件度量[J].软件学报,2000,11(5):1321-1330
[5] 王忠杰,徐晓飞,战德臣.基于特征的构件模型及其规范化设计过程[J].软件学报,2006(01):236-245