
在为您的业务选择服务器时,考虑用例非常重要。不同的用例需要不同的服务器配置,这会影响成本。
基本用例
对于基本用例,例如托管网站或简单应用,您需要的是一台配备以下配置的服务器:
2 个 vCPU4 GB RAM50 GB SSD 存储
这类服务器的月租金约为 50-100 美元。
中等用例
对于中等的用例,例如托管需要更多处理能力或内存的应用,您需要的是一台配备以下配置的服务器:
4 个 vCPU8 GB RAM100 GB SSD 存储
这类服务器的月租金约为 100-200 美元。
高级用例
对于高级用例,例如托管需要大量处理能力、内存和存储的大型应用,您需要的是一台配备以下配置的服务器:
8 个 vCPU16 GB RAM250 GB SSD 存储
这类服务器的月租金约为 200-400 美元。
按用例比较服务器成本
下面是不同用例的服务器成本比较表:
| 用例 | 服务器配置 | 月租金 |
|---|---|---|
| 基本 | 2 个 vCPU、4 GB RAM、50 GB SSD 存储 | 50-100 美元 |
| 中等 | 4个 vCPU、8 GB RAM、100 GB SSD 存储 | 100-200 美元 |
| 高级 | 8 个 vCPU、16 GB RAM、250 GB SSD 存储 | 200-400 美元 |
选择服务器时需考虑的其他因素
除了用例外,在选择服务器时还需考虑以下因素:
运营系统:服务器运营系统会影响成本。Linux 通常比 Windows 更便宜。位置:服务器的位置可能会影响成本。在美国托管服务器比在其他国家/地区更贵。供应商:不同的供应商提供不同的服务器价格。货比三家以获得最优惠的价格。
结论
通过考虑您的用例和上述其他因素,您可以选择满足您业务需求并符合您预算的服务器。
云服务器 谁家的便宜
阿里云。
主要推荐阿里云,腾讯云,华为云,那么这几家云服务器价格比较,哪家的价格比较划算,这三家云服务器经常搞活动,经常有非常超值的价格。
先看阿里云,其ECS云服务器价格,新客户首购,最便宜的是ECS共享型n4。
阿里云轻量应用服务器最便宜。
为什么轻量应用服务器比ECS还贵,主要是轻量应用服务器带宽峰值为5M,ECS最基础版带宽只有1M,所以轻量服务器贵一些。
西部数码推出的云服务器爆款有这几款:
爆款1型:2核2G 50G1M智能多线。
爆款2型:2核4G100G5M电信线路。
爆款3型:4核4G100G8M智能多线。
爆款4型:2核4G50G 5M智能多线。
爆款5型:4核8G100G10M电信线路。
爆款6型:2核4G100G100M电信线路。
用例的程序设计·用例
那么,到底什么是Use Case呢?在UML的文档中,Use Case的定义是:在不展现一个系统或子系统内部结构的情况下,对系统或子系统的某个连贯的功能单元的定义和描述。
有点拗口,对吧?其实Use Case就是对系统功能的描述而已,不过一个Use Case描述的是整个系统功能的一部分,这一部分一定要是在逻辑上相对完整的功能流程。
在使用UML的开发过程中,需求是用Use Case来表达的,界面是在Use Case的辅助下设计的,很多类是根据Use Case来发现的,测试实例是根据Use Case来生成的,包括整个开发的管理和任务分配,也是依据Use Case来组织的。
对不同的Actor来说,他要使用系统的某项功能也不同。
所以,在识别和分析Use Case时,我们要对每个Actor逐一进行。
对于ToDo User,我们可以轻易的识别出两个Use Case:Add Task 和 Remove Task。
ToDo User主动使用这两个Use Case所描述的系统功能,所以在我们的Use Case图上,ToDo User和这两个Use Case的关系是用从ToDo User发出的箭来表示的。
对于FileSystem,我们识别出的也是同样的两个Use Case,不过这次箭头从Use Case指向FileSystem,表示FileSystem是被动的。
Use Case可以用很多方式来描述,我们可以用自然语言(英语,汉语,随您的便),可以用形式化语言(哇!太酷了吧!),也可以用各种图示。
在UML中,通常用两种图来描述Use Case,它们就是顺序图(Sequence Diagram)和协作图(Collaboration Diagram)Use Case 由以下元素组成:名称简单描述事件流关系活动图和状态图Use Case 图特殊需求前条件后条件 1.1 参与者和用例从用户的角度来看,他们并不想了解系统的内部结构和设计,他们所关心的是系统所能提供的服务,也就是被开发出来的系统将是如何被使用的,这就用例方法的基本思想。
用例模型主要由以下模型元素构成: 参与者(Actor)参与者是指存在于被定义系统外部并与该系统发生交互的人或其他系统,他们代表的是系统的使用者或使用环境。
用例(Use Case)用例用于表示系统所提供的服务,它定义了系统是如何被参与者所使用的,它描述的是参与者为了使用系统所提供的某一完整功能而与系统之间发生的一段对话。
通讯关联(Communication Association)通讯关联用于表示参与者和用例之间的对应关系,它表示参与者使用了系统中的哪些服务(用例),或者说系统所提供的服务(用例)是被哪些参与者所使用的。
以银行自动提款机(ATM)为例,它的主要功能可以由下面的用例图来表示。
ATM的主要使用者是银行客户,客户主要使用自动提款机来进行银行帐户的查询、提款和转帐交易。
通讯关联表示的是参与者和用例之间的关系,箭头表示在这一关系中哪一方是对话的主动发起者,箭头所指方是对话的被动接受者;如果你不想强调对话中的主动与被动关系,可以使用不带箭头的关联实线。
在参与者和用例之间的信息流不是由通讯关联来表示的,该信息流是缺省存在的(用例本身描述的就是参与者和系统之间的对话),并且信息流向是双向的,它与通讯关联箭头所指的方向亳无关系。
1.2 用例的内容用例图使我们对系统的功能有了一个整体的认知,我们可以知道有哪些参与者会与系统发生交互,每一个参与者需要系统为它提供什么样的服务。
用例描述的是参与者与系统之间的对话,但是这个对话的细节并没有在用例图中表述出来,针对每一个用例我们可以用事件流来描述这一对话的细节内容。
如在ATM系统中的提款用例可以用事件流表述如下:1. 用户插入银行卡 2. 输入密码 3. 输入提款金额 4. 提取现金 5. 退出系统,取回银行卡 但是这只描述了提款用例中最顺利的一种情况,作为一个实用的系统,我们还必须考虑可能发生的各种其他情况,如银行卡无效、输入密码错、用户帐号中的现金余额不够等,所有这些可能发生的各种情况(包括正常的和异常的)被称之为用例的场景(Scenario),场景也被称作是用例的实例(Instance)。
在用例的各种场景中,最常见的场景是用基本流(Basic Flow)来描述的,其他的场景则是用备选流(Alternative Flow)来描述。
对于ATM系统中的提款用例,我们可以得到如下一些备选流:备选流一:用户可以在基本流中的任何一步选择退出,转至基本流步骤5。
备选流二:在基本流步骤1中,用户插入无效银行卡,系统显示错误并退出银行卡,用例结束。
备选流三:在基本流步骤2中,用户输入错误密码,系统显示错误并提示用户重新输入密码,重新回到基本流步骤2;三次输入密码错误后,信用卡被系统没收,用例结束。
… 通过基本流与备选流的组合,就可以将用例所有可能发生的各种场景全部描述清楚。
我们在描述用例的事件流的时候,就是要尽可能地将所有可能的场景都描述出来,以保证需求的完备性。
1.3 用例方法的优点用例方法完全是站在用户的角度上(从系统的外部)来描述系统的功能的。
在用例方法中,我们把被定义系统看作是一个黑箱,我们并不关心系统内部是如何完成它所提供的功能的。
用例方法首先描述了被定义系统有哪些外部使用者(抽象成为Actor),这些使用者与被定义系统发生交互;针对每一参与者,用例方法又描述了系统为这些参与者提供了什么样的服务(抽象成为Use Case),或者说系统是如何被这些参与者使用的。
所以从用例图中,我们可以得到对于被定义系统的一个总体印象。
与传统的功能分解方式相比,用例方法完全是从外部来定义系统的功能,它把需求与设计完全分离开来。
在面向对象的分析设计方法中,用例模型主要用于表述系统的功能性需求,系统的设计主要由对象模型来记录表述。
另外,用例定义了系统功能的使用环境与上下文,每一个用例描述的是一个完整的系统服务。
用例方法比传统的SRS更易于被用户所理解,它可以作为开发人员和用户之间针对系统需求进行沟通的一个有效手段。
在RUP中,用例被作为整个软件开发流程的基础,很多类型的开发活动都把用例作为一个主要的输入工件(Artifact),如项目管理、分析设计、测试等。
根据用例来对目标系统进行测试,可以根据用例中所描述的环境和上下文来完整地测试一个系统服务,可以根据用例的各个场景(Scenario)来设计测试用例,完全地测试用例的各种场景可以保证测试的完备性。
Ivar Jacobson在1967年定义爱立信AXE系统的构架时开始书写使用场境usage scenarios。
二十世纪八十年代中期Jacobson花了很多精力来思考过去十多年的工作方法。
他造了一个术语anvendningsfall,大意是“使用情况”(situation of usage)或用况(usage case)。
但当用英文出版的时候,他发现“useage case”在英语里说不通,所以写作用例“use case” 用例是短文用例可以是一个场景,包括动作和互交。
用例可以是一组场景,描述不同场景下的行为。
这种书写格式可以在任何时候描述有变体的行为,例如黑盒需求,业务流程,系统设计说明。
用例里不要有系统设计用例里不要有界面设计用例里不要有特性列表用例里不要有测试用例应该描述行为需求用例的主场景不要超过九步。
可以在适当的层次上得到子目标和移除设计说明。
用例的最大价值不在于主场景,而是在于备选行为。
主场景可能只占用例长度的四分之一到十分之一。
Use Case具有一个基本事件流(可称为理想路径)、多个例外流,包括:基本变化特殊情况处理错误情况的异常事件流 Use Case 说明书应包括以下内容:功能描述可用性可靠性性能可支持性设计约束 试图决定Use Case的大小是一个很有趣的话题,处理这件事的一个方法是将Use Case的大小跟它的意图和范围关联起来,对于一个真正大的范围来说,一个Use Case并不要在一个系统中处理那么多,但这些系统都用于同一商业领域,称为Business Use Case,它把整个公司看作一个黑盒和Actor关于公司目标的说明。
这些Business Use Case的场景不允许假定任何公司内部的结构,一个客户将向公司下一个定单而不是客户服务部门。
对于系统发展而言,Use Case的范围限制一个单一的系统,这是Use Cases最通常的形式,我们称之为System Use Case,它把整个系统看作是一个黑盒,它不指定任何内部结构并且仅受限于问题域的语言描述。
Use Cases的另一范围是设计子系统和系统内部组件的,称为Implementation Use Cases,它把组件看作一个黑盒,并且这些Actors是区分它的成员。
例如:可能会用Implementation Use Cases去说明应用系统中email组件的需求。
给出了这些分类,关于Use Case的大小话题变得容易了,设计这些项的范围来调整整个大小。
帮助系统设计者,每个Use Case只描述没有大的分支的行为的单个线索。
违背这个规定,Use Case看起来通常是不准确的或含糊的,作为测试说明的资源和参考,它也是很难使用的。
Use Cases的好处是一些情节能用不同程度的正规化的文字说明。
每个情节涉及Use Cases中单一的途径,细节是条件组。
不正规的文本描述也能使用,不过当条件较多和可能失败的情况下它们很难跟随下去。
开始试图理解需求时,不正规的叙述风格也是非常有用的,然而随着Use Cases的进展,使用更加正规的机制去说明Use Cases才是有用的。
下面是客户对Use Case“下定单”的粗略概略:“确定客户,找出需要的并且仓库里还有的物品并检查客户信用额是否够用”结构化叙述的格式已经被证明是非常有效的。
这个格式所做的事是描述每一个情节的行为者:目标语句对顺序的叙述。
在这个顺序中,每一个行为者:目标的语句对都假设前一个的目标是成功的,右面是一个简单的范例:Use Cases认为我们正在设计的系统是一个单一的黑盒,根本没有任何内部结构被记录下来,并且它被认为是一个情节产生的目的及对应单一的行为者(Actor)。
这些Use Cases没有表示任何关于系统内部的东东,只是表示系统将达到什么样的目标及由什么(人或其它系统)操作和负责。
Use Cases已经得到越来越广泛的应用,它与其它需求捕获技术相比,它成功的原因在于:1 Use Cases把系统当作一个黑盒2 Use Case 使在需求中看到实现的决定变得更加容易最后一点源于第一点的补充,一个Use Case没有指定任何这些需求相关的系统的内部结构,所以说,如果这个Use Case中陈述了提交改变到定单数据库、显示结果到Web页面等的话,那么内部结构是显而易见的,并造成对设计的潜在约束。
为什么这些需求不指定内部结构的原因是,说明的内部结构给设计者带来了额外的约束,没有这些约束设计者们能更自由地建立一个正确实现客观可见行为的系统,并存在出现突破方案的可能性。
这里是Use Cases的图形符号描述,UML中一个单一的Stick-Man符号标示角色(Actor),用椭圆标示Use Cases,如这些图对于你想看到Use Cases之间如何关联的大图和获得系统上下文的大体描述来说是非常重要的。
Use Cases图没有显示不同的场景,它们的意图是显示角色和Use Cases之间的关系。
所以Use Cases图需求用结构化叙述文本来补充。
UML提供一些可供选择的图来显示不同的场景,这些常规的图形有交互图、活动图、顺序图、状态图等(本文暂不讨论这些图)。
使用这些图的主要缺点是它们不象文本一样是紧密的,但它们能用于给出Use Case的整体感觉。
是否每个Use Case 都包括至少一个actor?是否每个Use Case 都独立于其他Use Case?是否每个Use Case 都有一个简单的行为或事件流?是否每个Use Case 都有一个唯一的、直观的、可扩展的名称,使它不至于在后期被混淆。
用户是否容易理解Use Case 的名称和描述。
Use Case模型显示系统中的Use Case与Actor 及其相互关系。
其评价标准有:Use Case 模型是可理解的吗?通过对Use Case 模型的研究是否能对系统功能有一个清晰的概念。
所有的actor都定义了吗?所有的功能需求都满足了吗?Use Case 模型是否存在多余的行为。
从模型到Use Case包的划分是否是恰当的。
由于具有简单的图形符号、易理解的自然语言说明书,Use Case在文档系统和软件需求领域成为一 项越来越受欢迎的技术。
Use Case对开发小组极具吸引力,即使小组成员对正式的需求文档没有经验,但这些简单性却具有欺骗性,即使项目小组在开始使用Use Case 时没有任何麻烦,当他们将其应用于大项目时常常会遇到许多同样的问题。
1 使用 use case 十大误区1. 系统的boundary 没有定义或经常改变;2. 从系统观点而不是actor观点来定义Use Case;3. Actor的名称不一致;4. Use Case 定义过多;5. Use Case 和actor之间的关系象蜘蛛网一样错综复杂;6. Use Case的说明太长;7. Use Case的说明不清楚;8. Use Case没有正确的描述功能需求;9. 用户无法理解Use Case;10. Use Case 无法正常结束。
2 如何避免以上问题清楚的确定系统的boundary.简单来说,系统的boundary就像一个加了标签的盒子,actor在盒子外,而Use Case在盒子内。
我们称之为系统的这个盒子究竟是什么呢?一个计算机系统?一个应用系统?或一个完整的企业?…Use Case 可以用来合理地描述任意系统。
但一次只能用来描述一个系统,在一个系统中恰当定义的actor和Use Case用于另一个不同的系统中就会出现错误。
使用标准模板书写Use Case 说明书Use Case 图形符号已经被标准化并作为对象管理小组UML的一部分,但自然语言的Use Case 说明书还没有被标准化。
为了成功书写Use Case 说明书,我们需要一个标准模板来保证Use Case 的一致性。
关注actor的真正目的,从actor的观点而不是系统观点来命名Use Case面向Use Case 的需求与传统的功能性系统需求之间最显著的区别在于actor ,以面向Use Case的观点,系统存在是由于actors 要通过该系统实现某些目标,actor与系统进行交互来实现其目标,我们将这些交互行为定义为Use Case 。
不要将Use Case 说明书与用户接口设计相混淆现在有一种很流行的观点:由于Use Case 是actors 与系统之间的交互,所以将所有的用户接口设计图放在Use Case说明书中是一个好办法。
初看时,这的确很有用,因为它将在说明书中描述的actor/系统之间的交互行为以图的形式表示出来,非常直观。
但是这样做的负面影响却远远大于其好处,用户接口设计可能会随着时间而改变,我们不应该让系统需求依赖于用户接口设计,相反地,用户接口设计应该满足Use Case 需求。
如果我们将用户接口设计置于Use Case 说明书中,当需求需要被认可和定为基线时,很自然地,这些设计元素可能仍然在改变,这就使得用户接口设计成为不完整的、不正确的和/或不一致的。
将用户接口设计置于Use Case 说明书还会出现另一个问题,为了在Use Case 之间和接口之间建立一对一的通信,我们会选择反映用户接口的Use Case块而不是反映用户目标的Use Case 块,这样,为了表达一个完整的用户目标,我们使用交互Use Case 关系,将不同的、基于用户接口的Use Case 联接起来,结果在Use Case 模型中,我们得到了一幅类似蜘蛛网的关系图。
实际上,这副图是用户接口说明图,虽然它在系统文档中是很重要的一部分,但他属于用户接口设计文档,而不是Use Case 需求文档。
实现用户接口和Use Case 交互之间的松散耦合松散耦合是比较合适的,低逼真度的用户接口图有助于理解Use Case ,但要注意不要过度的将基本交互与用户界面机制相连,用户界面很有可能会改变。
在功能说明书中,要注意actor做些什么(如提交请求)而不是交互是怎样完成的(如双击提交按钮)。
不要在Use Case 和用户接口之间建立通信试图在Use Case 和用户接口之间建立通信可能会存在潜在的、不正确的功能操作。
Use Case 不仅与只能访问某个接口的actor相联,而且与那些能够更新该接口的actors相连(这可能是例外流),结果就造成了不正确的功能操作。
我们应该在基于实际用户目标和功能操作的基础上拆分Use Case ,而不是在基于用户接口的基础上组合Use Case ,只有这样才能得到正确的Use Case 模型。
回顾Use Case 模型和Use Case 说明书,如果你不能防止所有的误区,你应该尽早认识问题并确定问题这个观点并不是什么新东西,有关代码检查的经典算法已有大约25年历史了,但怎样将其应用于Use Case 呢? 首先,回顾Use Case 模型,回顾一下Use Case 的简单说明(Use Case 名称、目标、简单描述)。
这项工作应在绘制草图时尽早执行,并在写详细的Use Case 说明书之前完成。
接着是回顾Use Case 草图,保证图是正确的,并且详细的Use Case说明书是完整的。
最后是正式回顾最终的Use Case 图和Use Case 说明书。
我们发现这种三阶段式回顾比单一的宇宙大爆炸式回顾有效,在我们花大量的时间写说明书之前,Use Case图中存在的许多实质性问题可以被发现,这种方法减少了当需求改变时需要做的重复工作。
主要行为者(Actor)和Use Case之间没有连结一些情况下,从Use Case中取值的行为者(Actor)和积极参与这个Use Case的行为者(Actor)之间没有清晰的连结。
如:财务主管能成为“发票确认”的行为者(Actor),但他未必是创建发票的人。
这不是什么问题,这个Use Case仍然是正确的,它正说明行为者取值和设计的系统的范围外的Use Case发生的初始化之间的关系。
主要行为者是有用的,因为这个人扮演的角色是当你说明Use Case时需要跟他说的人。
情节步骤不需要连续情节中步骤顺序的情况是没问题的,这里有一些机制去突出可能的并行步骤。
在UML中活动图是首选的机制,通过非正式地看Use Case的情节你可以注意到可能的平行步骤;可以看Use Case内一些邻近的步骤;也可以有相同的行为者(Actor)对步骤负责。
之前我们举过的例子里,确认数量和确认信用额可能是平行的。
有时候在Use Case的说明文档中标记这些可能的平行步骤是有用的。
Use Cases的大小当开始做Use Cases的时候有个很显然的危险就是它要么有很多步骤要么就很少步骤。
如果在Use Case中有超过15个步骤,它可能包含一些实现明细。
如果它只有非常少的步骤则检查它的目标是否是达到一个没有很多分支的活动的单一线索。
较少的人类行为者(Actor)如果Use Case有较少的人类行为者,而大多数行为者是其它系统,通常的做法是修改这个Use Case。
寻找系统必须做出反映或公认的事件胜过会见这些行为者。
需求捕获和系统复杂性总而言之,这些情节捕获到系统复杂度的同时行为者:目标语句对容许大的系统以相对压缩的格式说明。
Use Case的格式的作用是用户和开发者能标志出行为者,然后确认这些行为者工作职责对应(或不对应)的目标,代替一个大的很难读的功能规格说明书。
仅仅这样,用户和开发者就有足够的兴趣进而研究那些情节的细节。
系统不仅仅有应得的功能性需求一些Use Cases并没有捕获所有的客观需求,仅仅是捕获了系统怎么用的那些功能性需求。
然而还有许多方面的需求需要去捕获的。
其中有的非功能性需求使用关联以至于也能隶属于个别的Use Case,如性能需求和系统容量的需求。
另外的一些不是关联的而是要单独地去捕获,它们是以下的需求:· 系统范围· 系统用户的目标· 用户界面原型· 一般规则· 约束· 算法运行时期和建立时期的需求比较一个重要的因数要记住,就是系统的赞助者是大过用户团体的。
系统中有许多的风险承担者,Use Cases仅仅捕获其中一些风险承担者的需要,具体说,Use Cases仅仅捕获系统运行时期的需求而忽略做为系统开发组织的风险承担者的需求,开发组织最有兴趣的是对建立时期需求的描述。
运行时期需求包括:系统范围、用户组织对产品的期望和目标、Use Cases、其它非功能性需求。
建立时期需求包括:减少开发成本、较少的变更处理、现存组件的重用。
建立时期的需求可以部分的由Use Cases把握。
但许多方面是需要由开发组织的处理的。
· 项目范围和目标:项目必须提交什么。
(和系统范围的区别是它提交的是所有项目的东西)· 增长性和变更请求:这些可以在捕获为常规Use Cases格式中的“Change Cases”· 开发负责人的约束:包括标准、习惯、工具、品质度量标准、品质保证原则、及品质保证的习惯。
Use Cases首先用于需要响应客观事件的系统。
它们能用于提供了一个有很容易理解的目标的清楚的行为者的环境。
当结果不可定义或不清晰时不能用Use Cases。
意思是如果目标成功或目标失败不能有一个明确的定义,那么Use Cases不能用来捕获需求。
然而说到这,现在大部分对象方法都使用Use Cases。
因为Use Cases被证明是捕获需求的非常有效的机制。
Use Case 是系统提供的功能块,换句话来说Use Case演示了人们如何使用系统。
通过Use Case观察系统,能够将系统实现与系统目标分开,有助于了解最重要的部分――满足用户要求和期望,而不会沉浸于实现细节。
通过Use Case 用户可以看到系统提供的功能,先确定系统范围再深入开展项目工作。
谈谈需求的描述-用例(Use Case)
用例(Use Case)是一种描述系统需求的方法。
运用用例这种方法来描述系统需求称之为用例建模。
用例也是UML规范中的一种标准化的需求表达方式,其中比较有名的RUP(Rational Unified Process)就是以用例来驱动的。
值得一提的是,虽然RUP被认为是一种重量级的软件管理过程,而越来越多的软件开发开始采用敏捷方法来响应瞬息万变的需求变化。
但是用例作为一种描述需求的方式,其理念和方法论对我们分析需求还是有一定的帮助。
从表达方式上看,用例相对时序图、流程图等需求表达方式,更加面向对象和面向设计。
通常情况下,用例比较容易让没有受过专业培训的人员接受。
用例可以作为一种跟用户或者行外人员陈述需求的方式。
用例是一种描述需求的方法,用例描述了在不同的条件下,系统对参与者的请求做出的响应。用例通常通过一个参与者(Actor)(
谁?
)向系统做出请求,系统根据参与者的请求(
要做什么?
),在不同的条件下,执行某一行为序列(
系统怎么满足?
)。每一个行为序列可以称之为一个场景(Scenario),一个用例包含多个场景。场景也可以称之为用例的一个实例(Instance)。
正式的用例应该包括:用例名、概述、范围、级别、主参与者、项目相关人员和利益、前置条件、最小保证、成功保证、触发事件、主成功场景、扩展场景和相关信息等等。
各个组成部分的意义如下:
用例可以用于不同的目的,如:
不同的编写目的导致了用例在编写过程中有可能出现不同的侧重点。
在不同的团队情况也可能导致用例书写的不一样。
比如在一个大型的开发项目组里,就需要严格的按照用例范例进行描述,而在一个小型的沟通频繁的项目组里,则可以采用一种比较简单的描述方式。
上文提到的是比较常见的组成部分。
事实上,用例的格式并没有硬性规定,在必要时可以增减里面的信息。
具体用例需要包括哪些信息,有不同的流派。
有兴趣可以查看相关资料,这里不展开讲。
一句话概括: 你的用例不是我的用例,只有适合的用例才是最好的 。
本文主要观点均来自于《编写有效用例》(Writing Effective Use Cases )作者是 Alistair Cockburn。
有兴趣的可以读一下原著。
用例用于表述需求,但是有两点要注意的:
用例名用于标识一个用例,便于汇总和阅读。
规则:使用主动语态的动宾短语来描述。
一般情况下,建议使用主动语态的动宾短语来描述用例的目标。如:
“查找商品”
、
“加入购物车”
。在某些情况下,如需要更准确的表示出一个用例,可以加入定语进行修饰,如:
“用户清除购物车”
、
“管理员清除购物车”
。
规则:以主参与者为对象进行描述。
用例的描述需要以主参与者为对象进行描述,如可以使用
“支付订单”
(以主参与者为对象),而不是
“收取订单费用”
(以系统为对象)。
用例的范围能让我们对系统的边界和讨论的需求有一个基础的语境,不同的设计范围可能会导致我们需要讨论的参与者、场景都会不一样。
简单来讲,就是为我们讨论的系统划定一个范围确定我们讨论的界线。
例如我们要讨论一个用户的下单行为。
如果以整个企业为范围,其项目的相关人员为用户、第三方服务者(如快递等)。
但如果以系统为范围,其项目相关人员还应该包括企业内部的系统管理员、客服等。
所以,在编写用例时需要搞清楚,我们的用例的范围是什么,这样可以对用例讨论的问题达成一个共识。
在讨论用例的设计范围时,需要先确定系统的功能范围。Cockburn在《编写有效用例》里面推荐了一个确定功能范围的方式
“内/外列表”
。
确定功能范围的好处是显而易见。
如,系统外部已经有了一个打印订单的系统,如果不明确区分系统的功能范围,部分开发人员有可能会对打印订单功能进行设计和实现。
而事实上,这些功能是不需要设计的。
明确了功能范围后,还可以确认系统的执行人员。如上面的例子,打印订单系统将作为
“打印订单”
用例的辅助执行者。
设计范围是在功能范围确定了之后做的。
设计范围指的是我们在编写用例时讨论问题的边界和对象。
我们在用例里面说的范围(Scope)如果没有特殊说明指的就是设计范围(而不是功能范围)。
下面来看一个例子,ECom公司打算做一个ESys的系统,系统里面包括了ESubSys等多个子系统。
如果以ECom为设计范围来讨论用例,我们关心的是用户对公司的需求是什么,公司以什么样的形式满足用户的请求。
如果有外部公司,则还要考虑外部公司与公司之间往来的业务是什么。
如果以ESys为设计范围来讨论用例,我们更关心用户向系统发起的请求和系统对请求的响应。
同时,如果以ESys做范围的时候,企业内部的员工也成了用例的执行者,我们还应该考虑员工对系统的请求。
确定用例范围,能很好的对其我们要讨论的问题是什么,界定我们讨论问题的范围,给用例一个语言环境。
规则:设计范围是一个简单的专有名称。
用例的范围应该是一个简单的专用名词,简单说明一下用例讨论的范围界线。如,上面的例子中范围可以直接用
、
、
来表示。
主执行者是系统相关人员中,请求系统做出响应的人或物。
主执行者是对系统请求的发起者,可是 主执行者可以不是直接操作系统的相关人员 。
其中一种情况下是主执行者通过另一个系统操作相关人员对系统进行操作。
如,客户致电客服查询异常订单的场景。
客户并没有直接通过系统进行查询。
另一种情况是定时触发任务。
如客户希望系统定时执行一个任务,那么最终执行系统的相关人员是系统本身。
虽然识别出主执行者很重要,可是在有些时候 主执行者也没那么重要 。
在编写用例时,识别出主执行者,可以从执行者角度出发,充分梳理系统需求。
我们还可以主执行者的特点来设计系统的交互。
如下表,主执行者概括表:
在多数情况下,我们开始编写用例开始后,主执行者就变得没那么重要了。
例如,当我们在设计查询订单用例时,无论是管理员、经理、客服甚至是其他的公司职位,在查询订单这个用例上并没有特别的差异。
这个时候,主执行者具体是谁已经不重要了。
规则:用例的主执行者可以是执行者或者执行者角色。
在上述情况下,我们会将部分主执行者一般化的方式,创建一个
“角色-执行者对应表”
。在上述用例里,我们将管理员、经理等一般化为一个操作角色——订单管理者。我们在描写用例时,以角色作为主执行者即可。
概述主要用于描述用例的目标,也就是用户需要完成的目标。
规则:使用自然语言描述。
尽量使用自然的语言阐述用户要完成目标时,用户会做什么事情。
规则:描述用例实现什么,而不描述系统步骤。
只需要讲清楚用例需要完成的事情即可,这里不需要描述系统步骤或者用户的具体操作流程。
如:
“用户选择一件需要购买的商品后,可以将商品加入购物车,然后在购物车里面提交订单。
用户也可以不需要加入购物车,直接购买选中的商品。
”
概述并不需要描述具体的系统操作,在这里并没有描述
“点击加入购物车按钮”
等系统的操作细节。
项目的相关人员是指对系统有特定利益的参与者。
相关人员不一定是人,也可以是一个外部系统、一个组织等。
所以能成为项目相关人员的有可能是:
主执行者
主执行者是发起执行用例的相关人员。
辅助执行者
辅助执行者是为被设计的系统执行服务的的外部执行人员。
辅助执行者可以是另外一个系统、也可以是一个人或组织。
如,一台打印机,为系统打印各种票据。
再如,快递公司,为系统提供快递服务,并提供物流信息。
内部执行者
内部执行者是在系统内部关注系统利益的相关人员。
被设计的系统
被设计的系统本身有时候对自己也是有特定利益的。
对于相关人员,有几点需要说明:
规则:相关人员和利益用以对应列表的方式书写。
使用
<相关人员>:<利益>
的方式,描写相关人员和其关注的利益。
在编写用例过程中,我们有时会具体描述一个用户的需求(如用户购买商品),有时候会描述一个系统的具体功能(如用户登陆),有时候会描述一个流程(如购买商品并获得商品的流程)。
在编写用例的时候,知道用例所处的位置,对我们编写和理解用例有很大的帮助。
我们将用例级别从总到分划分成了三个层次:概要、用户目标、子功能。
用户目标是指主执行者使用系统期望获得的目标。用户目标是我们编写用例的重点。用户目标描述了主执行者通过系统
“做一件什么事”
,以及做完这件事后
“用户能获取什么利益”
。
用户目标应该是主执行者一次执行系统获取利益的过程。
所以,不是一次执行所能完成的目标,或者用户不能获得利益的需求不能称为用户目标。
如,购买一个商品的流程,这个从下订单到快递需要几天的过程,所以不能称为一个用户目标。
再如,用户登陆,用户登陆并不能获取什么利益,所以也不能称为一个用户目标。
用户下单这个操作,可以作为一个用户目标。
概要层次可以包含多个用户目标,概要目标执行周期比用户目标更长,可以是一个几天、几个月甚至更长的过程。概要目标有三个目的:
子功能层次是用户目标在执行过程中会执行到的目标。
如,一次登陆,一次订单打印等。
也有可能存在多个用户目标共用一个子功能,如查找商品、查找订单等。
子功能用例的存在是为了用户目标用例增加可读性而存在的。
在实际编写过程中, 不到迫不得已,不要设计子功能层出用例 。
规则:层次只有三个选项:概要、用户目标、子功能。
用例的层次只能是概要、用户目标、子功能三个之中的一个层次。
前置条件是我们在用例执行之前期望必须成功的条件。在用例编写过程中,可以不对该条件进行检查和讨论。如,
“下订单”
必须依赖于
“用户已经登陆”
这个前置条件。
规则:前置条件必须是用例执行前我们期望一定成功的条件。
要预防将那些并不是必须条件的条件写入前置条件。
如,取消订单并不依赖于用户下单成功,事实上,用户可以将下单不成功(例如支付失败)的订单取消掉。
而订单下单是否成功这个条件是需要在用例里面对这个条件进行检查并执行不通过动作的。
最小保证是用例执行无论是否成功都会被执行的保证。
虽然,用例无论执行成功与否,最小保证总会被执行。
但是,最小保证更多的是为用例执行失败情况下,为用例相关人员提供的利益保证。
最小保证可以有多个。
一个常见的最小保证例子是
“系统将用户执行记录日志”
,就算用例执行失败,用户的操作也将会被记录到日志里面。
成功保证是指用例执行成功后,用户所能得到的利益保证。
相关人员的利益能否得到保证,是用例执行成功的判定条件。
成功保证可以有多个。
例如,在下订单用例中,用户下单成功后,必须保证
“订单被创建,并提交到后台处理。”
触发事件是指用例启动的事件,用例将通过触发事件,开始一步一步执行。
规则:触发事件是跟系统交互的第一个操作。
以用户下单用例为例子,用户决定要购买商品后,在系统中查找商品并下单。那么
“用户决定要购买商品”
并不能作为用例的触发事件,事实上,用户更系统的交互是从
“查找商品”
开始的,所以
“用户查找商品”
才是用例的触发事件。
我们讨论用户跟系统交互时,还应该注意我们讨论的系统的范围。特别是当主执行者不是直接操作软件系统的场景时,更应该明确系统范围。如,
“用户致电客户经理下单”
这样的场景下,我们的系统范围并不能限定在软件系统范围内,这是系统范围是公司。所以,
“用户致电客户经理”
跟我们系统交互的第一步,所以可以成为
“触发事件”
。
主成功场景是用例从触发事件开始,一步一步执行,最终满足用例利益的步骤集合。
主成功场景应该包括以下信息:
执行步骤应该有一些简单的规则:
规则:使用简单语法。
使用简单语法结构:
例如:
规则:准确描述执行者之间的切换。
执行步骤需要准确描述步骤执行过程中,执行者之间的切换。如,
“用户致电客户代表”
,我们可以知道步骤已经从用户切换到了客户代表。
但是,有时候在执行者明确的情况下,也有可能不会出现在句子中。如,
“用户输入密码”
,我们也可以知道这个步骤的执行者已经从用户切换到了系统。我们不必使用
“用户向系统输入密码”
这种冗余的描述方式。
规则:从系统外去描述步骤。
不应该从系统内部,或者全部以系统角度去考虑而已。
而应该从系统外去描述步骤。
如果从系统内部去描述步骤,可能会写成:
如果在系统外部去描述步骤,则表述成:
规则:显示过程向前推移。
一些小的步骤只能完成少数工作,有时候这些工作并不能很好的描述过程在向前推移。如,
“用户点击了确定按钮”
。这个步骤并不能很好的描述过程在向前推移,用户的真实目的是登陆系统,随着用户登陆系统,用例步骤可以继续往下执行。
规则:显示执行者的意图,而不是动作。
执行者通常是通过操作系统执行一个动作的,在描写用例时,容易将用户动作和执行者的意图搞混。
例如: 1. 系统要求用户输入身份信息 2. 用户输入用户名密码 3. 用户点击确定按钮 4. 系统确认用户身份信息 ……
用例过多描述了系统操作界面和用户的动作,如
“要求用户输入身份信息”
,这个并执行者的意图,而只是一个交互动作。
我们可以缩减描述用户动作的步骤,将用例改成:
规则:包含合理的活动集。
描述步骤的时候,并不一定要求每个步骤之包括一个活动。
根据需要可以将部分活动集合在一个步骤里面。
如:
这个步骤也可以描述成两个步骤:
用例的描述方式以简单,有效为主,有时候并不拘泥于具体的方式。
事实上很多开发团队都形成了自己的用例编写规范。
规则:步骤描述成功的场景,而不要体现可能的失败。
主成功场景的步骤描述的是成功的步骤。例如:
如果这样编写步骤,我们将要继续考虑
“如果判断正确……”
,
“如果判断失败……”
。但是在主成功场景的步骤中,是不体现失败的步骤的。所以,需要将步骤改成
如果如果系统验证失败怎么办?这部分信息放到扩展里面描述。
下文会详细说明,这里不展开。
规则:当步骤不连续执行是,可以加入时间限制。
多数情况下,步骤是一步接一步执行的。可在某些时候,可以这样描述:
规则:一个步骤可以涉及多个相关人员。
我们有时候需要通过一个系统向另一个系统发起一个执行动作,可以写成:
规则:可以反复执行一个或多个步骤。
有时用户会反复执行其中一个或多个步骤,这时候需要在步骤中增加一定的描述。如:
扩展是主成功场景的分支,是指主成功场景在一些其他条件下会完成的不同动作。
请注意,使用“扩展”而非“异常”或“错误”,事实上扩展包括了成功和失败两种可能的条件 。
其基本的逻辑是,在执行主成功场景时,如果系统……(检测到意外),那么,……(做一些事情)。
常见的有可能出现扩展的场景如下:
在这些场景出现后,我们应该在扩展中描述这些场景处理方式,然后回到主成功场景或者退出用例。
扩展是针对主成功场景的,所以我们写编写扩展的时候,需要用编号来表明扩展的对应关系:
主成功场景如下:
扩展如下:
如果是每个步骤都可能会触发的扩展,可以用”*“号来表示,如:
或者如果是某些步骤触发的共有条件,可以加上步骤来表示,如:
规则:从系统检测到的角度去描述扩展条件。
扩展条件应该是系统能检测到的条件,而不是发生了什么。
如,用户忘记密码了,系统不可能检测到用户是否密码或者是其他的什么原因。
从系统检测到的角度去描述,系统只能检测到用户输入错误的密码或者用户输入超时。
规则:合理化合并扩展条件。
扩展条件事实上无需枚举出所有的可能出现的场景,和合理的范围内,我们可以将一些扩展条件合并成等价项。判断等价项,有两个标准:
例如,用户输入密码的步骤里面,用户可以忘记密码输入错误,也可以手误输入错误或者其他的可能性,这些条件都是系统不可以检测的条件。
首先,将这些条件转换成系统可以测试的条件:密码输入错误。
转换后,所有条件就可以合并成一个了。
在来看一下系统可以完成的条件,如,密码输入错误、用户名错误、用户名不存在等,我们系统的处理都是
“提示用户名或密码错误或不存在”
。这时候可以将条件合并成
“系统检测到用户名或密码输入错误”
。
还有一种情况,如果在低层级(如子功能级别)用例已经完整描述了扩展,那么在其高级别(如用户目标级别)用例,可以不用重复冗余描述。比如,在子功能级别用例
“保存数据”
里面已经完整描述了保存过程中可能出现的各种扩展条件,那么在其上级用例里就可以不用描述了。
— 用例还能以用例图的方式来表示。
本文主要是通过用例的关注点和用例的组成来探讨一下一种需求的描述方式,所以就不对用例图召开介绍了。
有兴趣的读者可以自行参考其他资料了解。
在敏捷开发越来越受到推崇的今天,用例这种相对较“重”的需求分析和表达模式越来越少的被人使用。
当是我们通过研究用例的关注点和分析方式,其很多思想还是可以借鉴到我们日常的需求分析当中的。

