1、1UML 建模风格之状态图UML 状态图描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的时间做出反应的。通常我们创建一个 UML 状态图是为了以下的研究目的:1. 研究类、角色、子系统、或组件的复杂行为。 2. 建模实时系统。 指南概要当行为的改变和状态有关时才创建状态图把初始状态放置在左上角把最终状态放置在右下角状态指南状态名称要简单但应具有描述性避免 “黑洞 “状态避免 “奇迹 “状态子状态建模指南为复杂的目标建模子状态把通用的子状态变换放在一起为复杂的实体创建一个分层的状态图最高阶的状态图总有初始态和最终态变换和动作用实现语言的命名规则命名软件动作用叙述性文
2、字命名角色动作只有对所有的入口变换都合适时才注明入口动作只有对所有的出口变换适合时才注明出口动作只有当你想终止并再进入该状态时才建模递归变换2用过去式命名转换事件把转换标记放在接近源状态的地方以转换方向为基础放置变换标记警界点警戒点不应该重叠为可视化的定位警戒点而引入接合点警戒点不必配套一致的命名警戒点一、通用准则1.当行为的改变和状态有关时才创建状态图 敏捷建模( AM) ( Ambler 2002)的原则最大化项目干系人的投资建议你只有当模型能够提供正面价值的时候才创建模型。 如果一个实体,比如一个类或组件,表示的行为的顺序和当前的状态无关,那么画一个 UML 状态图可能是没有什么用处的。
3、例如一个SurfaceAddress 类就很简单,表示了那些你将会在系统中显示和操作的数据,因此一个UML 状态图就没有任何相关之处。而一个 Seminar 对象就非常的复杂,学生注册这样一个事件将会根据它的当前状态有不同的反应,就像你在图 1 中看到的。图 1.班级注册的一个 UML 状态图。2.把初始状态放置在左上角 如你在图 1 所见的,初始状态被建模成一个实心圈,把初始状态放在左上角反映西方人的阅读文化的习惯。3.把最终状态放置在右下角3 如你在图 1 所见,最终状态被建模为一个带边界的实心圆。把最终状态放右下角反映了西方的文化的从左到右,从上到下的阅读习惯。二、状态指南 状态是一个实
4、体的行为模式的某个阶段。 状态的表示是通过实体的属性值。 例如,在图 1 中,当 seminar 被标记为 open,并且存在空位的时候,seminar 就处于 Open For Enrollment 的状态。1.状态名称要简单但应具有描述性 象 Open For Enrollment 和 Proposed 这种的状态名称很容易理解,从而提高了图的沟通价值。理论上状态名称应该是现在时,但是用过去式写成的诸如 Proposed 的名称要比用现在时写成的诸如 Is Proposed 的名称好的多。2.避免“黑洞“状态 黑洞状态是那种只有变换进来但没有任何变换发出的状态,这种情况要么由于该状态是一个
5、最终状态,要么就是你已经错过了一个或多个变换变换。3.避免“奇迹“状态 奇迹状态是那种只有变换发出但没有任何变换进来的状态,这种情况要么由于该状态是一个起点,要么就是你已经错过了一个或多个变换变换。三、子状态建模指南1.为复杂的目标建模子状态 图 1 中展示的 UML 状态图是不完整的,因为它没有建模 Seminar 的 post - enrollment(注册后)状态。 图 1 建模了一个 Seminar 的完整的生命周期,把图 1 描述为一个新的包括子状态集合的 Enrollment 的复合状态,也称作超状态。 注意按理说你会像图 1 的模型那样处理标记,但为了简化起见在原先变换上的标记都
6、没有包括在内。当一个现有状态表现出复杂的行为时,建模子状态就是有意义的,从而促使你来研究它的子状态。当几个现有状态共用一个通用的入口条件或出口条件( Douglass 1999)时,引入超状态是有意义的,在图 1 中你可以看到所有的状态共用一个通用的 closed 变换,以到达最终状态。4图 2.Seminar 的完整生命周期2.把通用的子状态变换放在一起 和图 1 中每一个子状态都拥有一个 cancelled 变换不同,在图 1 中你可以看到cancelled 变换仅用于描述 Enrollment 超状态,这使图形得到简化。 如果子状态都共享一个入口变换或出口变换,都可以使用一个同样的方法。
7、 变换上的警戒点和动作(如果有)也应该使相等的。3.为复杂的实体创建一个分层的状态图 虽然这种表现子状态的方法是很好使的,但是最终的图可能变得相当复杂我们只要设想一下如果 Being Taught 状态也有子状态的话,图 1 会变成什么样就知道了。 一个替代的方法是创建一个分层的 UML 状态图。 例如,图 3 表示高阶视图,而图 1 描述了一个细节视图。这种方法的好处是如果需要的话,马上就可以建立一张详图来研究 Being Taught 状态。图 3.Seminar 的高阶状态图。4.最高阶的状态图总有初始态和最终态 一个高阶的 UML 状态图,例如图 2 描述的这样,应该表示实体的完整的生
8、命周期,包括“出生“和最后的“死亡“。 低阶的图未必包含初始状态和最终状态,特别是那些建模一个实体的生命周期的“中间状态“的图。5四、变换和动作 变换是从一种状态到另一种状态的序列,它可能是通过一个事件触发的。简而言之就是被建模的实体的内部或外部的行为。 对一个类来说,变换一般是将会导致状态的重要改变的操作调用的结果,因此我们需要了解一点,并不是所有的方法调用都会导致变换产生的,这一点非常重要。 一个动作就是某个东西,对类来说就是一个操作,被建模的实体所调用的操作。1.用实现语言的命名规则命名软件动作 图 1 中的动作遵循 Java 操作的命名规则( Vermeulen et. 2000),因
9、为系统使用 Java做为实现语言,如果我们的目标是两外一种语言,那么我们也需要遵循适当的命名规则。2.用叙述性文字命名角色动作UML 状态图可用于建模非软件实体的生命周期,特别是 UML 图上的角色。 例如学生角色就可能有诸如 Accepted、Full Time、Part Time、Graduated、Masters、Doctoral、和Post - Doctoral 等状态,以显示各人的不同行为。 当你在建模现实世界的角色时,与软件中 Student 类不同的是,状态间的变换最好是使用叙述性文字来描述,例如 drop seminar 和 pay fees,而不是 dropSeminar (
10、)和 payFees (),因为现实生活中的人是做事情,而不是执行操作。3.只有对所有的入口变换都合适时才注明入口动作 在图 1 中你可以看到 Closed To Enrollment 状态的入口中操作 notifyInstructor ()都是经由 entry/动作标记来调用的。 这暗示着每次进入状态时都需要调用该操作,如果你不希望每次都发生,那么就把动作关联到特定的入口变换。 例如,addStudent ()动作是在 student enrolled 变换到 Open For Enrollment 变换发生,而在到 opened 变换则不会发生,这是因为每次你在进入该状态并不需要增加一个学
11、生。4.只有对所有的出口变换适合时才注明出口动作 出口动作,用 exit/标记来表示,工作方式类似于入口动作。5.只有当你想终止并再进入该状态时才建模递归变换 一个递归的变换是那些两个端点都拥有相同状态的变换。 一个重要的暗示是实体从状态出来,又回到原有的状态,因此,那些由于 entry/或 exit/动作标记而被调用的任何一种操作都可能被自动调用。 图 1 的 Open For Enrollment 状态就是这种递归变换的例子,因此当前班级大小就在入口处被记录下来。6.用过去式命名转换事件 图 1 中的转换事件,例如 seminar split 和 cancelled,是使用过去式命名的,反
12、映了这样一个事实:变换是事件的结果因为事件发生在变换之前,因此应该用过去式命名。67.把转换标记放在接近源状态的地方 虽然图 1 比较复杂,变换标记尽可能放在靠近来源的地方,例如 seminar split 和student enrolled。8.以转换方向为基础放置变换标记 为了更易于判断哪个标记和变换是一起的,按照如下的规则来放置变换标记:1. 在变换线条上的从左到右。 2. 在变换线条下的从右到左。 3. 变换线条右边的往下。 4. 变换线条左边的往上。 五、警戒点 一个警戒点是为了穿过一个转换而必须为真的一个条件。1.警戒点不应该重叠 离开状态的相似变换上的警戒点必须彼此一致。 举例来
13、说,x 0的警戒点是一致的,而 x = 0 的警戒点就不是一致的,因为他们重叠了,它并没有明确的指出当 x 为 0 时将发生什么。在图 1 中,你可以看到警界点的一致性,从填写注册表活动出发的该学生划线变换上的警戒点没有重叠,决策点上的警戒点也一样。2.为可视化的定位警戒点而引入接合点 在图 1 中你可以看到从 Being Taught 触发 student dropped 事件存在两个变换,而图3 中仅有一个,变换被合并了,因此我们需要一个接合点(填满的圆)。 这种方法的好处是现在图上的两个警戒点更彼此接近了,更容易看出警戒点是否重叠。3.警戒点不必配套 一个状态的变换警戒点有可能是不完整的
14、。例如,一个 bank account 对象可能从Open 状态变换到 Needs Authorization 状态,这时需要一个大额存款“large deposit“的警戒点。可是,一个带有“small deposit“的警戒点的 deposit 变换可能并不需要建模,它是被隐含的,我们遵循了 AM 的实践简单的描述模型和仅仅包括相关的信息。4.一致的命名警戒点 图 1 包含了诸如 seat avaliable 和 no seat avaliable 的警戒点,两个警戒点的描述是一致的。 然而,诸如 seats left、no seat left、no seats left、no seats avaliable、seat unavaliable 之类的描述就是不一致,而且难于理解的。