By 高焕堂 2008/07/04
Use Case对象与Domain对象之结合
1. 两种对象之区别
从流程分析常得到许多功能模块,或称为功能对象(Functional Object, 或Use Case Object)。不过,只偏重于功能对象会产生蛮大的副作用。就如Gossain提到[Goss98, p.33]:
「从use cases去寻找物件是有危险的。Use Cases本质上是依循功能分解思维的,是依据功能的不同而将系统分解为许多use cases,然后按Jacobson的建议而找出各use case里的控制、实体和接口对象,这些对象都为特定use case而量身订制。虽然能从use cases找出一些潜在的对象,但很容易掉入陷阱---- 就是得出太多的功能对象。」
(Ientifying objects using use cases can be dangerous. Use cases are functional in nature and therefore, identifying different control, entity, and interface objects for each use case, as suggested by Jacobson, can lead to a set of fine -grained, ill-defined objects that are dedicated to the use case from which they were derived. It is possible to identify good candidate objects from use cases, but it is easy to fall into the trap of creating too many functional objects.)
于此先定义功能对象(即功能模块)吧!当我们在古典的功能分解(Functional Decomposition)思维引导下,而对系统进行分而治之,将系统分解为较小、较容易管理的单位时,此种单位称为功能模块(Functional Module),简称为「模块」。 在领域分析方法里,人们使用概念分解(Conceptual Decomposition)思维,对系统进行分而治之,将系统分解较小、较容易管理的单位时,此种单位称为概念模块(Cnceptual Module),又简称为组件(Component)或对象(Object)。无论是模块或组件,在计算机软件里,都能以类别或对象表示之。所以,希望您不要迷失于「模块」或「组件」的名词中,应该重视它的形容词:Functional 或Conceptual,也就是说,两者都是对象,只是分析途径不同,而采取不同的分而治之方法而已。请您先看一个例子,当我们依据功能分解方式,从一个半导体工厂的产品不良率统计程序里分解出数个小程序:
Darw2DPieChart(产品别)
Draw2DBarChart(厂区别)
Darw3DPieChart(产品别)
Draw3DBarChart(Lot批量别)
统计不良率(产品别)
统计不良率(Lot批量别)
计算批变异值(Lot批量别)
……
上述已经切分出许多小的功能(functions),然后把用法或做法相近的功能集合(group)在一起,并定义在计算机语言中的类别(Class)里:
// Functional Objects范例之一
class PieChart {}
class 2DPieChart extends PieChart {
void Darw2DPieChart(产品别)
{ 实作指令 }
void Draw2DBarChart(厂别)
{ 实作指令 }
}
class 3DPieChart extends PieChart {
void Darw3DPieChart(产品别)
{ 实作指令 }
void Draw3DBarChart(Lot批量别)
{ 实作指令 }
}
class 分析不良率 {
void 统计不良率(产品别)
{ 实作指令 }
void统计不良率(Lot批量别)
{ 实作指令 }
}
class 分析变异值 {
void 计算批变异值(Lot批量别)
{ 实作指令 }
}
这种对象称为功能对象(即功能模块)。如果把此观点对应到日常生活中,因为筷子与扫把的用法相似,只是对象不同罢了。就把筷子、扫把等工具归于同一类,然后替该类别取个名称,就成为对象类别了。于是得到如下有趣的情形:
// Functional objects范例例之二
class 器具 {
碗、筷子、碗匙
扫把、畚箕
}
class 储库 {
饭、菜、汤
垃圾
}
这令人觉得不太卫生!依循这个思维来看待自然界的事物时,就如下了:
// Functional objects范例之三
class 花瓣 {
玫瑰花瓣
莲花瓣
郁金香花瓣
…..
}
class 花蕊 {
玫瑰花蕊
莲花蕊
郁金香花蕊
…..
}
class 榇叶 {
玫瑰衬叶
莲花衬叶
郁金衬叶
…..
}
上述的功能对象并没有错,只是就欣赏者(User)的角度而言,把美丽的玫瑰花拆开来,分散于不同的类别,其行为实在不美,不是吗? 以上是从欣赏者的角度而得出对事物的一个观点而已,当我们依循另一个角度时就会得出另一个观点。从不同观点来认知事物通常会更接近事实,就像用两只眼睛看东西,会更有距离感。上述的概念性分解就是另一种角度,而得出新的观点。这两种观点是互补的。[歡迎光臨 高煥堂 網頁: http://www.cnblogs.com/myEIT/ ]
再来,看看概念对象吧!例如上述的统计图例子,以新的观点表达如下:
// Conceptual objects范例之一
class 产品 {
void Darw2DPieChart()
{ 实作指令 }
void 统计不良率( )
{ 实作指令 }
}
class厂区 {
void Draw3DBarChart()
{ 实作指令 }
}
class Lot批量 {
void Darw3DPieChart()
{ 实作指令 }
void 统计不良率()
{ 实作指令 }
void计算批变异值()
{ 实作指令 }
}
这就是概念对象,其类别名称大多为名词,而不是动词了。再来看看上述日常生活的例子,如下:
// Conceptual objects范例之二
class 筵席 {
饭、菜、汤
筷子、汤匙、碗
}
class 垃圾堆 {
垃圾
扫把、畚箕
}
这比前面所述的功能对象:器具、储库等,看起来更接近一般人的生活习惯。然而,就生产者(Developer)的观点而言,筷子和扫把是功能相近的东西,把它们放在一起比较好管理维护,例如在日常用品店里它们常会摆在一起卖。反之,就顾客(User)的观点而言,饭和筷子一起合作就能顺利吃饭,汤和汤匙也是常在一起的。例如餐厅的饭桌上,不是常看到它们摆在一起吗?所以上述的器具、储库等分类方式接近生产者观点,而筵席、垃圾堆等分类方式则比较接近顾客观点。还有上述「玫瑰花」的例子,其概念对象如下:
// Conceptual objects范例之三
class 玫瑰花 {
花瓣
花蕊
衬叶
…..
}
class 莲花 {
花瓣
花蕊
衬叶
…..
}
class 郁金香花 {
花瓣
花蕊
衬叶
…..
}
这比前面所述的功能对象:花瓣、花蕊等,看起来更具有自然而整体感。因为概念带来整体(whole)感,例如玫瑰花朵是由花瓣、花蕊、衬叶等部分(part)所组合而成的。基于「玫瑰花」概念而把玫瑰花蕊、玫瑰花瓣、玫瑰衬叶组合起来。就用户(User)而言,玫瑰花瓣和花蕊、衬叶天生就在一起,整体美感油然而生。反之,功能分析则以结构、功用或角色相似,而将之归为同类,并储存于同一模块里。所以上述的花瓣、花蕊等分类方式接近计算机内部处理的观点,而玫瑰花、莲花等分类方式则比较接近自然环境的处理观点。
2. 两者完美的结合
因为系统的用户(User)需求中,最优先的是功能性需求(Functional Requirements),可使用Use Case来表达一项功能需求,如图1所示:
图1、use cases像莲叶
我们能想象有一个对象来担任此项功能的执行,于是此对象就是功能对象。这是属于大颗粒的(Coarse-grained)高阶功能对象,即依据系统外部使用者的功能观点而设计的对象。它是依循功能分解而来,但是表达了使用者的观点。如下图:
图2、大颗粒的功能对象
上图的功能对象内为空心的表示其内部细节从缺,等待下层的概念对象来实现之。接下去,就采取概念分解(Conceptual Decomposition)方法,藉由企业领域里的概念做为分解的依归,定义出一群概念对象,并设计其合作(Collaboration)关系来支持上层的功能对象,此时也就设计而实现了上层的高阶功能对象,如下图:
图3、概念对象
此时已经定义了各概念对象,而且设计了它们之间的合作。此图里,有些概念对象内部为空心的表示其内部细节从缺,等待下层的功能对象来实现之。接下去,设计一些功能 对象来支持即实现上层的概念对象。如下图:
图4、两者相辅相成、完美结合
为什么会有下层小颗粒(Fine-grained)功能对象呢?原因有时是为了更佳的效率,有时是为了再利用(Reuse)既有的功能模块或功能对象。这种小颗粒功能对象通常是从生产者、设计者或实作者的观点,将功能、结构等相近的东西归类而成的。兹比较如下:
- 大颗粒功能对象---- 顾客观点,依据功能分解。
- 小颗粒功能对象---- 生产者、设计者或实作者观点,依据功能而归类。
现在拿上述的统计窗体为例,建立此种结构如下:
// 大颗粒功能对象之范例
class 产品各批不良率之统计窗体 {
void 印出窗体() {
product = new 产品();
for each lot of product{
lot.统计不良率( );
lot.Draw3DBarChart();
}}
// 概念对象之范例
class 产品 {
void Darw2DPieChart( ){
pie = new 2DPieChart();
pie.Darw2DPieChart(Self.产品别);
}
void 统计不良率( ) {
rate = new 分析不良率();
rate.统计不良率(Self.产品别);
}
}
class厂区 {
void Draw3DBarChart(){
pie = new 3DPieChart();
pie.Darw3DPieChart(Self.厂别);
}
}
class Lot批量 {
void Darw3DPieChart( ) {
pie = new 3DPieChart();
pie.Darw3DPieChart(Self);
}
void 统计不良率( ){
rate = new 分析不良率();
rate.统计不良率(Self.批量别);
}
void计算批变异值(){
obj = new 分析变异值();
obj. 计算批变异值(Self.批量别);
}
}
// 小颗粒功能对象之范例
class PieChart {}
class 2DPieChart extends PieChart {
void Darw2DPieChart(产品别)
{ 实作指令 }
void Draw2DBarChart(厂别)
{ 实作指令 }
}
class 3DPieChart extends PieChart {
void Darw3DPieChart(产品别)
{ 实作指令 }
void Draw3DBarChart(厂别)
{ 实作指令 }
}
class 分析不良率 {
void 统计不良率(产品别)
{ 实作指令 }
void统计不良率(Lot批量别)
{ 实作指令 }
}
class 分析变异值 {
void 计算批变异值(Lot批量别)
{ 实作指令 }
}
为什么需要中间层的概念对象呢?
- 大颗粒功能对象支持用户(User)观点,确保系统开发能Do the right thing。
- 概念对象支持领域专家(Domain Expert)观点,确保系统与企业成为一体的两面。
- 小颗粒功能对象支持开发者(Developer)观点,确保系统建置能Do the thing right。
参考数据
[Atki02] Colin Atkinson, etc., Ocomponent-based Product Line Engineering With UML, Addison-Wesley, 2002, ISBN:0-201-73791-4.
[Coad95] Peter Coad, Object Models:Strategies, Patterns, And Applications, PH, 1995, ISBN:0-13-149477-5.
[Goss98] Sanjinv Gossain, Object Modeling and Design Strategies, SIGS, 1998, ISBN:0-521-64822-x.
[Hei01] Geogre Heineman and William Councill, Component-Based Software Engineering, Addison-Wesley, 2001, ISBN:0-201-70485-4.
[Jac99] Ivar Jacobson, etc., The Unified Software Development Process, Addison-Wesley, 1999, ISBN:0-201-57169-2.
[Jac96] Ivar Jacobson, “Formalizing Use-Case Modeling”, Wisdom of the Gurus:A Vision of Object Technology, SIGS, 1996, ISBN:0-13-499849-9.
[Jac95] Ivar Jacobson, The Object Advantage, Addison-Wesley, 1995, ISBN:0-201-42289-1.
[Jac94] Ivar Jacobson, etc., ROAD Magazine July-August 1994, SIGS, 1994.
[Kular00] Daryl Kulak and Eamonn Guiney, Use Cases: Requirements In Context, Addison-Wesley, 2000, ISBN:0-201-65767-8.
[Martin92] James Martin, Object-Oriented Analysis and Design, PH, 1992.
[Rich99] Charles Richter, Designing Flexible Object-Oriented Systems with UML, MTP, 1999, ISBN:1-57870-098-1.
[Rum96] James Rumbaugh, OMT Insights, SIGS, 1996, ISBN:0-13-846965-2.
[Go Back]