用户模型是一种统一建模语言(UnifiedModelingLanguage,UML)类模型。该模型中的每个元素表示为一个应用了适当构造型的UML类。构造型化的UML特性和关联描述元素的属性和属性之间的关系。
在本文中,了解如何为一个简单场景构建用户模型。(UML屏幕截图来自IBMRationalSoftwareArchitect,Version7.0。)
场景
用户角色
构建用户模型的第一步是确定谁将使用该解决方案。用户的特征在用户模型中通过用户角色来刻画。用户角色描述一群具有相似需要和职责的用户。用户角色可以表示用户组织中将大量使用该解决方案的特定工作。或者,用户角色可以具有更细的粒度,仅包括执行不同类型的工作但需要以相似方式使用该解决方案的人员的一个共同工作方面。
用户模型包含许多用户角色。必须特别小心地确定所有类型的用户,因为忽略某个人员群体会在解决方案中导致脆弱性。用户角色应该基于用户群体的实际情况,而不是精心设计以匹配解决方案本身的设计。
在我们的安全组件场景中,存在拥有资源的人员和使用资源的人员。其中每个群体分别称为“资源所有者”和“业务用户”。
用户角色涵盖用户工作的一个方面,而不是代表某项完整的工作。用户角色不是互斥的。有些人可以是一个资源的资源所有者和另一个资源的业务用户。资源所有者甚至可以是他或她自己的资源的业务用户。只要某个个人一次仅扮演单个用户角色,就足以对这些用户角色进行区分了。
另一个用户角色是“审核员”,负责检查审核记录以确定谁正在访问每个资源。
最后,您需要考虑:
该安全组件具有以下用户角色:
每个用户角色在该用户模型中使用一个将构造型设置为<
图1.使用UML类定义的用户角色
在RationalSoftwareArchitect中,还为每个属性显示了图标,意味着该属性是私有的,并且在用户模型中不重要。
确定用户目标
每个用户角色应该至少定义一个用户目标。用户目标定义用户角色尝试达到的最终状态或目的。图2显示了“资源所有者”(ResourceOwner)用户角色的用户目标示例。
图2.资源所有者的用户目标
该用户目标的名称是“资源所有者”希望达到的状态。存在一个提供简短描述的<
<
因此,让我们将该用户目标修改为“资源访问受到正确控制”。此目标捕获了为什么资源所有者要使用该IT解决方案,但是没有描述如何使用。
定义了用户目标以后,就可以使用与<
图3显示了该用户角色与该用户目标之间的聚合关联。
图3.用户角色的主要用户目标
资源所有者的ProjectExplorer视图显示了资源所有者与该用户目标的<
图4.ProjectExplorer中用于关联的构造型
通过选择角色名称(在此例中为“资源访问受到正确控制”)将构造型应用于关联,以在相应的窗格中显示该角色的属性。ApplyStereotypes按钮在Stereotypes选项卡下,如图5所示。
图5.应用构造型
属性和关联按字母顺序出现在ProjectExplorer中。它们在图上的出现顺序是在ResourceOwner属性视图中的Attributes选项卡下定义的。
用户角色和技能集
图6.技能集
用户角色通过与<
在图7所示的示例中,存在一个资源所有者预期将具备的针对资源安全技能的技能集。此定义规定拥有某个资源的个人需要具备这些技能。
当添加了从ResourceOwner用户角色到ResourceSecurityPolicies技能集的关联时,该关联将出现在ResourceOwner的ProjectExplorer视图中。可以看到<
图8.<
对技能集建模涉及到指明哪些技能是某个用户角色特有的,以及哪些技能是某些或所有用户角色共有的。为此,您还要指明技能集之间的关系(使用聚合)。通常,表示高级技能的技能集具有与更基本的必备技能之间的聚合关系。
在图9所示的示例中,存在三个联系在一起的技能集:基本计算机技能(BasicComputerSkills)、个人用户安全性(PersonalUserSecurity)和资源安全策略(ResourceSecurityPolicies)。“资源安全策略”具有与“个人用户安全性”之间的聚合关系。ProjectExplorer视图表明该聚合已应用了<
图9.联系在一起的技能集
在对技能集建模以后,将不同用户角色所需要的技能做一下对比是非常有趣的。例如,图10表明“资源所有者”与“业务用户”具有围绕资源安全性的相同基本技能。因此,资源所有者具有操作业务用户的资源安全性用户界面的技能。
图10.用户角色和技能集之间的关系
在建模过程中的此部分,您将定义用户的预期技能级别。如果预期履行这些用户角色的人员不具备您指定的技能,则项目需要为这些用户包括培训资料,或者您可能需要尝试某种不同的方法。此分析在设计信息组织方式时也是非常有用的,因为它有助于揭示人员在何处可以履行多个用户角色。
构建词汇表
在为用户角色定义用户目标和技能集时,您会发现在名称和<
用户模型以用户对象和用户构件的形式,包含了该词汇表的正式定义。用户对象表示出现在用户界面上的虚拟概念。用户构件是物理的事物,例如文件和文档。
将要经历几次迭代才能完成该词汇表。在完成用户角色、用户目标和技能集的基本定义以后,就是在用户模型中构建该用户对象和用户构件词汇表的恰当时机了。
确定用户对象和用户构件
请考虑如图11所示的技能集。
图11.技能集
该技能集暗示存在以下类型的用户对象:
以及以下用户构件:
对于其中每个用户对象和用户构件,创建一个带有<
图12.创建UML类
如果不确定要使用<
添加用户属性
每个用户对象和用户构件可以定义用户属性,以表明用户角色了解有关这些用户对象和用户构件的什么信息。在图13所示的示例中,Resource具有六个属性:Name、Type、Owner、CreationTime、LastUpdateTime和Description。
图13.定义了属性的Resource用户对象
每个用户属性具有类型,此类型可以是以下类型之一:
用户属性始终应用了<
用户属性还可以具有<
图14显示了Resource用户对象的树形视图,并具有如下用户属性列表:AccessControlList、CreationTime、Description、LastUpdateTime、Name、Owner和Type。Name和Type还具有<
图14.Resource用户对象在ProjectExplorer中的树形视图
在使用该树形视图时,务必记住:
图15.关联
通过从属性中删除所有的构造型,然后以所需的顺序重新应用这些构造型,从而可以更改构造型的顺序以更改所使用的图标。
添加关联
用户对象之间的关系使用UML关联进行定义。使用了所有四种类型:双向、定向(单向)、聚合和组合。
在图6所示的示例中,用户构件AuditLog和用户对象AuditLogEntry之间存在一个组合(黑色菱形)。
图16.审核日志与其审核日志条目之间的组合关联
组合意味着一个用户对象是另一个用户对象的一部分。在该示例中,AuditLogEntry是AuditLog的一部分。基数设置为*,这意味着每个AuditLog中有零到多个AuditLogEntry。该关系的另一端的基数为1,这意味着每个AuditLogEntry仅出现在一个AuditLog中。
在图17所示的示例中,存在两个来自于UserGroup的聚合关联。聚合暗示两个用户对象之间的临时关系。来自UserGroup的第一个聚合关系环回到自身。这表示一个UserGroup可以列出其他UserGroup。两端的基数均为*,因此一个UserGroup中可以包括零到多个其他UserGroup,并且一个UserGroup可以包括在零到多个其他UserGroup中。
第二个聚合关联指向UserAccount,表示一个UserGroup可以具有零个或多个与之关联的UserAccount。此外,一个UserAccount可以包括在零个或多个UserGroup中。
图17.聚合关联
这是用于描述用户对象树的常见建模模式。您可以将UserGroup看作是树中的中间节点,将UserAccount看作是树叶。
图18显示了如何对AccessControlList建模。该关系具有一个来自于Resource的关联,表示AccessControlList是Resource的一部分。每个Resource有一个AccessControlList,并且一个AccessControlList只能属于一个Resource。
图18.AccessControlList是Resource的一部分
AccessControlList由多个条目构成,因此我们创建了一个名为AccessControlListEntry的新用户对象,如图19所示。
图19.具有多个条目的AccessControlList
起初,AccessLevel被定义为一个用户对象。经过深思熟虑之后,可以明显看出它实际上是AccessControlListEntry的一个用户属性。它可以具有的值是一个固定的值列表。如果希望在模型中硬编码这些值,可以使用一个UML枚举来对其进行建模,如下所示。
使用一个<
当使用动态枚举时,AccessLevel被指定给某个UserGroup或UserObject。可以使用继承来对此选择进行建模。定义一个名为AccessList的新用户对象,并通过其属性视图将其设置为抽象的。
图20.属性
由于AccessList是抽象的,其名称以斜体显示。
图21.斜体显示的抽象用户对象
UserGroup和UserAccount都继承AccessList,这意味着它们都是某种AccessList。
图22.两种使用继承的AccessList类型
AccessControlListEntry通过另一个聚合关联与AccessList联系在一起。由于AccessList是抽象的,AccessControlListEntry只可能指向某个继承AccessList的具体(非抽象)用户对象——在此例中为UserGroup或UserAccount。图23显示了一个示例。
图23.继承
定义用户对象筛选器
图24显示了Resource用户对象的两个筛选器的定义,这两个筛选器分别名为ResourceSelectionFilter和ResourceACLFilter。
图24.为Resource定义用户对象筛选器
ResourceSelectionFilter定义了在从列表中选择一个或多个Resource时非常有用的Resource属性。例如,当某个资源所有者希望选择要使用的资源时,该筛选器包含Name、Type、CreationTime和LastUpdateTime用户属性。当使用此用户对象筛选器来代替用户对象时,用户将不会看到Owner、Description和AccessControlList用户属性。
ResourceACLFilter仅包括Name和AccessControlList。诸如AccessControlListEntry等AccessControlList中的所有用户属性都将可见。
设计支持用户目标的用户任务
此时,您应该考虑如何完成每个用户目标。用户目标是通过执行用户任务来完成的。每个用户任务描述一个操作,用户执行该操作以实现全部或部分用户目标。用户任务的范围从粗粒度到细粒度不等。有些用户任务可以通过其他用户任务组合而成。然而,用户任务始终以对用户有意义的术语来表示。
用户任务使用具有<
图25.用户任务MaintainAccesstoResource的定义
用户目标通过一个单向关联与相应的用户任务联系起来。该关联应用了<
图26中的类关系图显示了从该用户目标到这些用户任务的三个关系。
图26.为实现用户目标而需要执行的任务
该ProjectExplorer视图显示了这些带有<
图27.<
如果您觉得可以描述一个明确的过程,该过程阐述某个用户目标如何转换为用户任务,那么该用户目标很可能是一个复杂的用户任务。在这样的情况下,您应该将其构造型更改为<
将用户任务与用户对象或构件关联起来
用户任务的行为是使用从该用户任务到某个用户对象、用户对象筛选器或用户构件的定向关联来进行建模的,如下所示。该关联上的构造型为<
图28.用户任务和用户对象(用户对象筛选器)之间的关系
每个action_target关联定义该用户任务中的一个步骤。关系上的<
验证匹配
需要验证用户任务与用户角色的技能匹配。在定义用户任务以后,我们将这些用户任务与执行它们所需要的技能集关联起来。要使用的关系是从用户任务到技能集的定向关联,如图29所示。该关联上的构造型为<
图29.定向关联
如果截止目前已定义的所有技能集似乎都不适合,则定义一个新的技能集并将其与用户任务关联起来。
图30.一致的关系环——用户角色具备执行某个用户任务的技能
将用户对象或构件与技能集关联起来
图31.技能集与用户对象或构件之间的关系
技能集与用户对象或构件之间的关联是双向的,并在技能集端具有<
结束语
本文说明了学习用于构建用户模型的符号和过程是多么简单。您只需基本了解UML类关系图和了解用于在用户角色之间进行区分的UML构造型。
有些开发团队曾经遇到过回答用户建模所引发的问题的困难。但是,这不是因为用户建模非常困难;而是由于对解决方案的用户了解得不够全面。用户建模的最大价值在于确定需求定义方面的差距,如果忽略这些差距,可能会导致非常糟糕的可用性(以及蒙受的所有成本和失败风险)。
用户建模可以揭示出何时需要通过联系参与者和用户以获取所需信息,从而执行更多的分析。一旦解决了不确定性,用户模型即可按照将对开发团队有用的形式捕获丢失的细节。其结果是获得该解决方案所支持的用户类型、那些用户需要的技能以及用户在使用该解决方案时所做的工作的有条理的定义。这实际上是构建解决方案用例的坚实基础。