我们比较了在Java编程语言以及UML建模语言这两种环境中类以及类之间关系在表达方式以及概念方面的差异下面我们要来看看UML Stereotype机制对于编写Java代码的影响
在Java程序中保留Stereotype
UML拥有一系列可用来扩展其核心概念的机制但最为人们熟知的也许就是StereotypeStereotype一般译作构造型它是一种扩展元模型语义的建模元素构造型必须基于元模型中特定的现有类型或类构造型可扩展已有类型和类的语义但不能改动它们的结构构造型默认的表示方法是在关键词周围加上尖角双括号这种双括号在某些欧洲语言中自然存在因为它很象两个尖括号所以用两个尖括号也是一种被认可的表示方式
构造型几乎适用于UML中的任何元素包括类属性操作以及关联等例如我们可以用构造型来显示UML图中一个类别的类图一显示了用构造型来表示State设计模式中一个类扮演的角色改编自《Design Patterns》一书UML定义了大量的标准构造型我们既可以使用这些标准构造型也可以定义自己的构造型
图一UML构造型用于表示类在设计模式中的角色
图一中的MessageStatus接口本来应该让interface这个词位于尖括号之内但是为了把接口和其他构造型区分出来用来制作本文UML图的Together ControlCenter工具已予以省略这是因为接口与其他构造型不同在UML元模型中接口也具有与类相似的特性
直到UML之前(年月)UML中的一个图形元素只能有一个构造型但在UML 中OMG(对象管理组织)取消了这个限制现在一个图形元素可以有多个构造型许多UML工具由于未能跟上这一变化所以仍没有提供这方面的支持
那么构造型对于我们的Java代码又有何影响呢?从某种意义上讲答案是完全没有因为Java没有提供任何让我们按照这种方式对类进行分类的手段(前面几篇文章已经讨论了接口和继承在UML中它们都有自己特定的表示方法)但是另一方面我们可以利用构造型更清楚明白地说明Java代码的含义首先约定构造型的具体意义然后在源代码注释中以一个新的javadoc标记的形式包含构造型有效地减少为了说明Java代码含义而需要手工编写的说明文字数量下面的代码片断就是图一Sent类的骨架代码构造型以一个定制javadoc标记的形式加入到了注释之中
/**
* @Stereotype concreteState
* @author AuthorName
* @version
*/
public class Sent implements MessageStatus {
}
在UML中并非只有类可以通过指定构造型而约束其定义图二显示了两个类之间的依赖关系用构造型来表示这种依赖关系的类型在这个例子中Factory类的对象负责创建Item类的对象Factory类的代码显示了定制的javadoc标记如何用构造型来简洁明了地说明这种依赖关系
图二加注instantiate构造型的UML依赖关系
符号说明在前面的文章中我们看到了三种类之间的关系这里出现的是第四种关联关系用一根实线加上开叉的箭头表示(如果关联关系是单向的话)一般化关系用实线加上封闭的箭头(从子类指向超类)表示Realization关系用虚线加上封闭的箭头(从实现接口的类指向接口)表示现在我们看到了第四种箭头与线型的组合虚线加上开叉箭头表示的依赖关系
public class Factory
{
/**
* @dependency <> Item * @return a new Item
*/
public Item createItem() {
return new Item();
}
}
操作和属性同样可以指定构造型如图三所示两个操作被加注了构造型用来表示它们是否会修改属性的值与图三对应的源代码同样利用定制的javadoc标记说明该方法的构造型信息
图三为类的操作加注UML构造型
public class Sale
{
/**
* @Stereotype query
* @return total price of sale
*/
public BigDecimal calcTotal() {
}
}
在java源代码中加上了描述构造型信息的定制javadoc标记之后好处不仅仅在于减少了需要手工编写的注释而且使得UML工具有可能处理这些标记并完成下面这类任务
从Java源代码重新生成(比没有定制javadoc标记的情况下)更加完整的UML图
在Javadoc生成的文档中增加额外的信息
例如本文所用的建模工具TogetherSoft的Together ControlCentre就是用这种方法来保留各种无法直接在Java源代码中保留的UML类图语义信息
其他表示方法
本文开头提到尖括号是显示构造型的默认方式实际上构造型还可以用改变图形符号或形状的方式表示图四的例子显示了两个带有<>构造型的类Cashier利用<>构造型的替代符号画出Manager类用默认的矩形画出在使用替代符号时很难再列出类的各种属性和操作所以通常省略还有第三种表示方法即在常规的矩形符号内的类名称右边放上一个很小的替代符号但现在这种表示方法已经不太见到了
图四<>构造型的替代符号
在类图中使用替代符号表示构造型有一个很大的缺点如果有些人不熟悉类图用到的符号要理解类图表达的是什么意思就很困难了另外多一种符号理解图形的负担就增加一分在这个系列的文章中我们只关注那些最常见的UML类图符号
除了用改变符号形状的方法来表示已经指定了某种构造型之外我们还可以通过改变图形元素的颜色或纹理来表达同样的信息运用色彩意味着我们可以保留常规的图形形状和符号同时又能表达出与改变形状同样多的视觉信息(如果不是更多的话)另外与抽象的形状相比简单的配色方案一般更容易掌握一些
图五在类图中运用色彩
图五的彩色类图运用了Peter Coad等人的四色原型(Archetype)组合来定义类
粉红色的<>类表示在一个系统中由于业务或者合法性的原因必须跟蹤的事件或活动CarSale和CarRental就是两个粉红色类的例子 黄色的<>类代表参与事件或活动的方式例如CarSalesperson和Customer都是黄色类的例子 绿色的类可进一步分成<>(通常是一个人或组织)<>(事件或活动发生的地点)以及>(实际涉及事件或活动的物体) 第四种原型是蓝色的catalogentrylikedescription(简称<>)表示的是诸如现实当中的汽车与展览目录中的描述之间的差异汽车型号属于蓝色的类它包含一系列的值和取值范围描述所有属于该类别的车而每一辆现实中的车则由绿色的<>来表示 属于特定原型的类具有或多或少相似的属性和行为属于同一原型的类还会倾向于以通常而言可预测的方式与其他原型的类交互这些特征和行为模式可以帮助我们快速构造出健壮的可扩展的对象模型迅速掌握有可能被忽略的属性和操作增强我们对代码结构的信心图五显示了我们可能在各种原型的类中找到的属性和操作以及各种原型之间的典型关系
结束语在这篇文章中我们了解了对于UML中一些很有用的概念如果它在Java语言中没有直接的等价概念如何在Java代码中利用UML的这些概念来保留高层次的设计思想在下一篇文章中我们将告别UML类图转而讨论UML另一种重要的图形——交互图包括序列图和协作图