流程图是一种通用的图形表示法,用以展示步骤、决策和循环等流程控制结构。它通常用于描述算法、程序执行流程或业务过程,关注于任务的顺序执行。流程图强调顺序、分支和循环,适用于详细说明具体的处理步骤,图形符号相对基础和通用。
活动图和状态图是流程图的特殊形式,都是UML(统一建模语言)的一部分,可以更专业规范帮你理解和设计系统的动态行为。活动图更侧重于描述系统中的活动执行顺序和业务流程,而状态图则更关注于描述对象的状态和状态转换。
一、活动图(Activity Diagram)
UML(统一建模语言)中的活动图是一种图形化表示方法,主要用于描述系统中的活动和流程,帮助开发人员更好地理解系统的执行过程和交互关系。
活动图的用途:
-
对系统工作流程建模
工作流:是一个良好定义的动作序列,执行时将产生一个可观察的值,或者产生一个个体或实体的对象。
-
对工程组织过程建模
-
对算法流程建模
1、活动(Activity)
活动代表了一个过程或者操作,通常用矩形框表示。
1.1. 动作状态
动作状态是指执行原子的、不可中断的动作,并在此动作完成后通过完成转换转向另一个状态的状态。
1.2. 活动状态
活动状态是可分解的,不是原子的,其工作的完成需要一定的时间。可把动作状态看作具体活动的特例。
一个活动可以分为若干个动作或子活动,这些动作和子活动本身可以组成一个活动图。
一个不含内嵌活动或动作的活动称之为简单活动;一个嵌套了若干活动或动作的活动称之为组合活动,组合活动有自己的名字和相应的子活动图。
- 组合活动有自己的名字和相应的子活动图:
- 一个包含子活动的活动和嵌套了子状态的组合状态类似,概念上也相对统一:
2、控制节点
用于控制活动的流程,如起始节点、结束节点、决策节点等。
- 起始节点:表示活动的起始点,通常用一个实心圆表示。
- 结束节点:表示活动的结束,通常用一个圆圈内带叉的符号表示。
- 决策节点:当需要根据特定条件选择不同路径时使用。
3、边的类型
3.1、控制流边
表示活动之间的执行顺序,是最常见的边类型。
-
直流:有一个输入流和一个输出流。
-
分支(Branch)与合并(Merge)
分支一般用于表示对象类所具有的条件行为。
条件行为用分支和合并表达。
一个分支有一个入转换和多个带条件的出转换,出转换的条件应当是互斥的。
一个合并有两个带条件的入转换和一个出转换,合并表示从对应的分支开始的条件行为的结束。 -
分叉(Fork)和汇合(Join)
分叉用于将动作流分为两个或者多个并发运行的分支,而汇合则用于同步这些并发分支,以达到共同完成一项事务的目的。
分叉可以用来描述并发线程。
汇合代表两个或多个并发控制流同步发生,当所有的控制流都达到汇合点后,控制才能继续往下进行。
3.2. 对象流边
用虚线箭头表示,表示活动之间的数据传递。
3.3.异常边:
用带有“<>”标签的箭头表示,表示活动执行过程中可能出现的异常情况。
4、泳道(Swimlane)
用于对活动图中的活动进行分组,描述对象之间的合作关系。泳道技术是将活动用线分成一些纵向区域,每个区域代表一个特定类、人或部门的责任区。泳道技术是活动图中引入的一种面向对象机制,可为提取类及分析各个对象之间的交互提供方便。
示例
假设我们要描述一个简单的购物流程的活动图,以下是可能的示例:
-
起始节点:标记为“开始购物”。
-
动作节点:
“浏览商品”:表示用户浏览可购买的商品。
“选择商品”:表示用户从浏览的商品中选择要购买的商品。
“添加到购物车”:表示用户将选择的商品添加到购物车中。
“结算”:表示用户完成购物并准备结算。
“支付”:表示用户进行支付操作。 -
控制节点:
“决策节点”:在“结算”节点后,可能有一个决策节点来判断用户是否选择了正确的支付方式或商品是否还有库存等。如果条件满足,则继续执行“支付”节点;否则,可能返回到“选择商品”或“浏览商品”节点。
结束节点:标记为“购物完成”,表示整个购物流程的结束。 -
边:使用控制流边连接上述的各个节点,表示活动的执行顺序。如果需要,还可以添加对象流边来表示数据传递,例如从“添加到购物车”节点到“结算”节点传递购物车数据。
这个示例展示了如何使用UML活动图来描述一个简单的购物流程。当然,在实际的项目中,活动图可能会更加复杂,包含更多的节点、边和图符来描述系统的活动和流程。
二、状态图(State Diagram)
状态(State)是对象在其生命周期内所呈现的一种特定条件或情境,这一条件或情境下,对象会满足特定的要求,执行相应的活动,或者等待特定事件的发生。每一个对象都拥有其独特的状态,这些状态是对象经过一系列操作或活动后的结果。一旦某个事件被触发,对象的当前状态便会随之发生变化,从而进入新的状态阶段。
UML(统一建模语言)状态图(Statechart Diagram)是一种用来详尽描述一个特定对象在其生命周期内所有可能存在的状态,以及这些状态之间由于不同事件触发而发生的转移和变化的图形化工具。它清晰地展示了对象在不同状态下的行为以及这些状态之间的转换路径,从而帮助开发人员深入理解和分析对象的动态行为。
本小节详细介绍了UML 状态图 的状态要素、状态分类,转移(Transition)要素、转移(Transition)分类,事件(Event)等内容。
1、状态
1.1、状态要素
一个状态在UML状态图中通常包含多个组成部分,它们共同描述了对象在某一特定情况下的行为和响应。以下是您提到的各个部分的详解:
-
状态名(Name):
状态名用于标识和描述对象在其生命周期中的某个特定状态。它通常是一个简洁且具有描述性的名称,如“待处理”、“进行中”或“已完成”等。 -
进入/退出动作(Entry/Exit Action):
- 进入动作(Entry Action):当对象进入该状态时,会执行的动作或操作。这些动作通常在对象从其他状态转移到当前状态时执行,用于初始化或准备该状态所需的环境或资源。
- 退出动作(Exit Action):当对象准备离开该状态时,会执行的动作或操作。这些动作通常在对象从当前状态转移到其他状态之前执行,用于清理或释放该状态所使用的资源或执行必要的后续处理。
-
内部转移(Internal Transition):
内部转移指的是在不改变对象当前状态的情况下,由于某些事件或条件的发生而执行的动作或操作。这些转移不会导致对象从当前状态转移到另一个状态,而是在当前状态内部执行某些操作或响应某些事件。 -
子状态(Substate):
子状态(也称为嵌套状态)是出现在另一个状态内部的状态。一个状态可以有零个或多个子状态,这些子状态表示了该状态的更细粒度或更具体的行为。子状态可以进一步包含它们自己的进入/退出动作、内部转移和子状态等。子状态的存在使得状态图能够更加详细地描述复杂对象的动态行为。 -
延迟事件(Deferred Event):
延迟事件是一种特殊的事件,它不会立即触发状态的转换,而是被延迟到对象的某个特定状态或条件满足时再执行。当对象处于某个状态时,如果接收到一个延迟事件,该事件将被暂存起来,直到对象满足执行该事件的条件或进入能够处理该事件的状态时才会被触发。延迟事件允许对象根据当前状态或条件来决定何时处理某个事件,从而实现了对事件处理的灵活控制。
示例:
横线上面是名字域,下面是转换域(可选)。
- entry/turnOn:当转入该状态时,做开灯动作。
- do/blinkFivetimes:当处于该状态时,灯闪烁5次。do活动是只在状态内出现的活动,不能附加到转换上。
- event poweroff/powerSupplySelf:当电源关闭事件发生时,用自备电源。
- exit/turnOff:当转出该状态时,做关灯动作。
- event selfTest/defer:当selfTest事件发生时,对象将延迟响应,到别的状态中再处理,用defer这个特定动作表示延迟。
通过以上组成部分,UML状态图能够全面、准确地描述一个特定对象的所有可能状态以及这些状态之间的转移和变化,为开发人员理解和分析对象的动态行为提供了有力的支持。
1.2、状态分类
状态可以细分为不同的类型,例如初态、终态、中间状态、组合状态、历史状态等。一个状态图只能有一个初态,但终态可以有一个或多个,也可以没有终态。
在UML(统一建模语言)中,状态图用于描述一个对象在其生命周期中可能经历的所有状态,以及由于各种事件触发而在这些状态之间进行的转换。UML状态图的状态可以分为几种主要类型,以下是对这些状态的详细解释:
-
初始状态(Initial State):
初始状态代表状态图的起始位置,表示对象生命周期的开始。在状态图中,初始状态通常用一个实心圆表示,并可能有一个指向它的箭头,表示对象从初始状态开始其生命周期。
一个状态图只能有一个初始状态,因为每个执行都是从同一个起点开始的。 -
终止状态(Final State或End State):
终止状态表示对象生命周期的结束或某个特定行为的完成。在状态图中,终止状态通常用一个含有实心圆的空心圆表示。
与初始状态不同,终止状态的数量可以不确定,也可以没有。一个对象可能经历多个终止状态,或者在没有达到任何终止状态的情况下结束其生命周期。 -
中间状态(Intermediate State):
中间状态是除初始状态和终止状态之外的其他状态,表示对象在其生命周期中的某个特定条件或状况。
中间状态可能包含进入/退出动作(entry/exit action),这些动作在对象进入或离开该状态时执行。它们也可能包含内部转移(internal transition),这些转移在对象处于该状态时由于某些事件或条件而发生,但不导致对象转移到另一个状态。
中间状态还可以包含子状态(substate),这些子状态表示该状态的更细粒度或更具体的行为。 -
组合状态(Compound State):
组合状态或称为复合状态,是一个包含其他状态(子状态)的状态。组合状态用于描述具有复杂行为或包含多个子行为的状态。这些子状态可以是顺序发生的,也可以是并发发生的。
组合状态至少包含一个域(region),用于容纳其子状态。子状态可以是简单的中间状态、终止状态,或者它们自己也可以是组合状态,从而形成层次结构。在组合状态内部,可以定义进入动作(entry action)和退出动作(exit action),这些动作在对象进入或离开组合状态时执行。
组合状态通常用于表示具有多个子阶段或子行为的复杂过程。例如,一个订单处理系统可能有一个“处理订单”的组合状态,其中包含“接收订单”、“验证订单信息”、“计算价格”和“发送确认邮件”等子状态。这些子状态按照特定的顺序或并发地执行,以完成整个订单处理过程。-
顺序子状态:如果一个组成状态的子状态对应的对象在其生命期内的任何时刻都只能处于一个子状态,即多个子状态之间是互斥的,不能同时存在,这种子状态称为顺序子状态。
-
并发子状态:有时组合状态有两个或者多个并发的子状态机,此时称组成状态的子状态为并发子状态。
-
-
历史状态(History State):
历史状态用于记住对象上一次离开复合状态(composite state)时所处的子状态。当对象重新进入复合状态时,它可以恢复到历史状态,从而避免重新遍历整个复合状态的所有子状态。
历史状态在处理复杂的嵌套状态或长时间运行的系统时特别有用,因为它们可以简化状态图的复杂性并提高性能。
示例:CD Player,running状态被打断到power on状态,再转回到running状态时,希望直接进入历史状态
- 伪状态(Pseudo State):
伪状态是一种特殊类型的状态,它不像普通状态那样表示对象在其生命周期中的某个具体条件或状况。相反,伪状态用于描述状态图中的控制流或逻辑结构。
常见的伪状态包括选择(choice)、分叉(fork)、汇合(join)等。这些伪状态用于表示在状态图中选择多个转移、并行执行多个活动或等待多个活动完成等情况。
通过使用这些不同类型的状态,UML状态图能够全面、准确地描述一个对象在其生命周期中可能经历的所有状态以及这些状态之间的转换和交互。这有助于开发人员理解对象的动态行为、识别潜在的问题并优化系统设计。
1.3、转移(Transition)
在UML(统一建模语言)状态图中,转移(Transition)是描述对象从一个状态变化到另一个状态的行为。转移是由触发事件(triggering event)引起的,当这个事件在对象处于某个状态时发生时,转移就会被激活,导致对象进入一个新的状态。
转移要素:
- 源状态(Source State):
这是转移开始的状态。在状态图中,转移从源状态的一个出口开始,指向目标状态的一个入口。 - 目标状态(Target State):
这是转移结束的状态。当转移成功执行时,对象将进入这个目标状态。目标状态在状态图中由转移箭头指向。 - 触发事件(Triggering Event):
触发事件是导致转移发生的原因。它可以是一个信号、消息、操作调用、时间事件(如超时)或改变对象属性的动作。当这个事件在源状态发生时,转移就被触发。 - 监护条件(Guard Condition):
监护条件是一个布尔表达式,用于确定当触发事件发生时是否应执行转移。如果监护条件为true,则转移会被执行;如果为false,则转移不会执行,对象保持在源状态。 - 动作(Action):
动作是在转移执行过程中可能发生的可选行为。它可以在转移开始时、过程中或结束时执行。动作可以是任何类型的操作或方法调用,用于更新对象的状态或执行其他任务。 - 转移标签(Transition Label):
转移标签用于描述转移的属性,包括触发事件、监护条件和动作。在UML图中,转移标签通常写在转移箭头的上方或旁边。
在UML状态图中,转移可以是简单的直线,也可以是带有分支或合并的复杂路径。通过组合使用不同类型的转移和状态,可以构建出复杂而灵活的状态图,以描述对象的动态行为和系统状态的变化。
转移分类
虽然UML标准并没有严格规定转移的分类,但根据其特点和应用方式,可以概括几种典型的转移类型:
-
外部转移(External Transition):
外部转移是对象在接收到外部事件(如消息、信号或操作调用)时触发的转移。这种转移描述了对象如何响应外部世界的刺激。 -
自转移(Self-Transition):
自转移发生在同一个状态内部,即对象接收到一个事件后,状态不改变,但是可能会触发一些内部活动或动作的执行。这用于表示对象在相同状态下处理事件并可能更新自身属性的情况。 -
内部转移(Internal Transition):
类似于自转移,但强调的是在状态内部发生的活动,不涉及状态本身的改变。它强调的是状态内部行为的连续性,而不是状态的切换。 -
并发转移(Concurrent Transition):
当系统中的多个状态或子状态可以同时进行转移时,这种转移称为并发转移。在UML中,通常通过并行区域表示,显示不同状态或子状态间的并发行为。 -
条件转移(Conditional Transition):
如果转移的发生依赖于特定的条件(称为监护条件或Guard),那么这就是条件转移。只有当监护条件为真时,转移才会触发。 -
事件驱动转移:
根据触发转移的事件类型,可以区分不同的事件驱动转移,常见的有:- SignalEvent: 由外部信号触发的转移。
- CallEvent: 由方法调用或服务请求触发的转移。
- TimeEvent: 由特定时间间隔或时间点到达触发的转移。
- ChangeEvent: 由属性值变化触发的转移。
-
层次转移(Hierarchical Transition):
在包含复合状态的状态图中,从父状态到子状态或子状态到父状态的转移可以视为一种特殊的转移类型,体现了状态机的层次结构。
这些转移类型共同构建了状态图的复杂行为模型,帮助设计者理解并定义系统在不同条件下的动态行为。
1.4、事件(Event)
在UML(Unified Modeling Language,统一建模语言)中,事件(Event)是状态机中的一个关键概念,它触发状态之间的转换或在状态内部触发动作的执行。事件代表了系统外部或内部的一个显著变化,这个变化足以影响系统的状态或行为。以下是UML中事件的一些主要类型和概念:
-
信号事件(Signal Event):
信号事件由外部源发送到对象或状态机,表示发生了某种感兴趣的事件。信号是UML中用于异步通信的基本机制。 -
调用事件(Call Event):
当一个操作被调用时触发的事件,这可以是直接方法调用或服务请求。它包括入口调用(调用一个状态或状态机的入口动作)和退出调用(调用一个状态或状态机的出口动作)。
-
变化事件(Change Event):
当某个监视的属性值发生变化时触发的事件。这种事件常用于实现状态机对外部或内部条件变化的响应。
用关键字When,后面跟布尔表达式。
-
时间事件(Time Event):
时间事件是基于时间流逝而触发的事件,如超时、周期性事件等。用关键字When 或After表示。
时间事件基于时间条件触发,分为以下几种:
- 绝对时间事件:在指定的绝对时间点触发。
- 相对时间事件:在某个持续时间过后或从上一个事件后经过一定时间触发。
- 时间间隔事件:每隔固定时间重复触发。
-
条件事件(Condition Event):
实际上这不是一个独立的事件类型,而是指使用条件(Guard)来限制其他类型事件触发转换的能力。当事件发生且条件满足时,转换才会执行。 -
中断事件(Interrupt Event):
中断事件可以打断当前正在执行的活动或转移,使系统立即响应紧急或优先级更高的事件。 -
复合事件(Composite Event):
由一个或多个基本事件组合而成的事件,所有组成部分必须同时发生或满足条件才能触发。
事件是状态图中状态转换的动力,它们与状态机中的监护条件和动作结合,共同描述了系统的动态行为和响应机制。在设计状态图时,明确每个转移所对应的事件及其条件,对于正确建模系统行为至关重要。
总结
活动图和状态图作为专业流程图在软件开发和其他领域中扮演着重要的角色。以下是它们的重要性:
-
清晰沟通:活动图和状态图能够以直观的方式展示系统的动态行为。这使得团队成员之间可以更加清晰地沟通,确保对系统功能和行为有共同的理解。
-
理解业务逻辑:活动图能够展示业务过程或操作流程中的各个步骤和决策点,帮助开发人员深入理解业务逻辑。状态图则能够清晰地展示系统中对象的状态转换,帮助开发人员理解对象的行为和生命周期。
-
问题发现与解决:通过活动图和状态图,开发人员可以更容易地发现系统中潜在的问题和瓶颈。这些图表提供了一种可视化的方式来分析系统的复杂性和可能的问题点,从而帮助团队在开发早期就发现并解决问题。
-
优化系统设计:活动图和状态图有助于开发人员优化系统设计。通过分析和优化流程图中的路径和转换,开发人员可以提高系统的性能和效率,减少不必要的复杂性和资源浪费。
-
支持变更管理:在系统开发过程中,需求变更或设计变更是常见的。活动图和状态图提供了一种灵活的方式来适应这些变更。通过更新流程图,开发人员可以快速地反映这些变更到系统中,并确保系统的稳定性和一致性。
-
支持文档化:活动图和状态图可以作为系统文档的一部分,为系统的维护和扩展提供重要的参考。这些图表能够清晰地展示系统的结构和行为,为后来的开发人员或维护人员提供有价值的指导。
总之,活动图和状态图作为专业流程图在软件开发和其他领域中具有重要的应用价值。它们能够帮助开发人员更好地理解系统、优化设计和支持变更管理,从而提高系统的质量和效率。