摘至 邹欣《构建之法》一书,以作学习之用
典型用户和典型场景
开发一个软件时,我们都知道要为用户考虑,但是用户在哪里/p>
典型用户的价值
所谓“Persona”,就是典型用户。在产品开发的过程中,我们经常需要描述一组典型的用户。以前大家通常是以一些抽象的名词来表示用户,如“家用电脑初学者”、“经验丰富的系统管理员”,现在我们建议用一个“典型用户”来代表。典型用户不再是一个抽象的概念,而应该是一个活生生的人物
典型用户一般有哪些特性个典型用户往往描述了一组用户的典型技巧、能力、需要、想法、工作习惯和工作环境
在设计软件的过程中,我们(设计/开发者)往往会以自己使用产品的习惯和对软件行业的熟悉程度出发设计,忘记了我们的软件是给千千万万个不那么会用电脑的人使用的。在这种情况下,搞一个“典型用户”会强迫我们在考虑问题时从用户的角度出发
怎样定义典型用户
怎样才能定义典型用户呢们首先要定义用户的角色。正如戏剧中有正面和反面的角色,软件系统中也有受欢迎的和不受欢迎的典型用户。如果用户有不同的安全需求,切记要定义不同的角色来适应这些需求。如下面的例子:
-
受欢迎的典型用户——指那些按设计者的期望使用系统的用户,如“ 站的购物者”
-
不受欢迎的典型用户——指那些有不正当目的的用户,如在一个房地产业主论坛中滥发房屋中介广告的用户——这些用户也许在别的系统中(如房屋中介论坛)是受欢迎的
典型用户只是我们的设想,还要和这些典型用户的代表交流,理解用户,理解他们的工作方式和需要。然后再修改,细化典型用户
从典型用户到场景
有了典型用户之后,我们还得决定每一个典型用户的目标——他/她使用系统想要达到什么目的(如:购物、卖产品、滥发广告……)。对于每一个目标,列出达到目标所必须经历的过程,这就是场景,也可以叫故事(Story)。注意,有些场景描述了成功的结果,有些场景描述了失败的结果。用户和系统有成百上千种可能的交互情况,写场景时要有针对性。下面是现实生活中一个银行从业者发的一条微博,他体会了“ATM无卡取现”功能的强大:
特意带上手机和令牌不带银行卡,感受一下我行ATM的无卡取现,结果连自助银行的门儿都没进去,不刷卡怎么开门啊……
如果这一重要功能的设计者在做需求分析的时候就模仿用户,设计场景,实地演一次戏,很快就能发现戏演不下去了
场景怎么写/strong>
-
首先针对每一个场景,设计一个场景入口(描述场景如何开始)
-
接着描述典型用户在这个场景中所处的内部和外部环境(内部环境指心理因素等)
-
然后给场景划分优先级,按优先级排序写场景
场景之间如何区分呢
- 找到这个场景的特殊之处,对于共同的流程可以一笔带过,重点描述场景中特殊的因素
- 把场景组织成一个故事,这样就能把一个完整的用户与系统交互的流程记录下来,以后进行产品演示或验收都可以以此为基础
例如:
场景
工作项序 128:商户上货,最后修改时间:2007/3/1
1. 背景
1)典型用户:吴小石头[主要]、刘兰[次要]
2)用户的需求/迫切需要解决的问题
-
a. 吴小石头:上货过程冗长,要反复输入相似的文字,出错之后不容易恢复
-
b. 吴小石头:上传图像文件较慢,各个图像的标定(正面、侧面、缩略图)较繁琐
-
c. 吴小石头:上货完成后,最后的商品信息展示的整体效果事先无法知道。还要手工标注哪些是新产品,哪些是老产品
3)假设:
- a. 商品信息展示功能已经完成
- b. 用户订阅某个商家的产品更新功能已完成
- a. 立即发布 // 选项a让他可以立即发布商品信息
- b. 保存,不发布 // 选项b让他可以保存资料,但是不立即发布
这次,吴小石头选择a, 页会检查输入的完整性,必要时给予提示
所有资料上传到 站后, 站会自动生成上传图像的各种缩略图(64×64、128×128、512×512等),并将该产品标注为“新产品”。同时,系统会根据规则(每个商户只能有10个新产品)把以前商品中的“新产品”标注去掉
在吴小石头完成这一操作后,如果用户刘兰订阅了商户“吴小石头”的产品更新,刘兰就会收到一封E-mail,或者是一条短信,告知她喜欢的商家又有新产品上市了
从场景到任务
有了场景,下面就由架构设计师和各个模块的负责人一起,沿着子系统/模块的所属关系把场景划分开。例如Stone项目的用户登录场景,就可以分为以下几项。
2. 逻辑层
子任务为:用户输入字段合法性处理,上传图像逻辑和缩略图处理,资料保存逻辑等。
3. 数据库
子任务为:资料读取的存储过程,图像的索引建立和维护等。
不同的任务将会把一个场景编织起来,虽然有多个开发者参与这项工作,但是应该有一个开发者对整个场景负责。得到开发任务后,我们就可以创建和分配测试任务
用例(Use Case)
和典型人物、典型场景的方法类似,用例(UseCase)也是很常用的需求分析工具。用例有这样一些 基本元素:
-
标题:描述这个用例要达到的目标
-
角色(Actor):和软件系统交互的角色,例如用户,其他实体,甚至时间(在描述一些和时间相关的场景时有用)
-
主要成功场景(Main Success Scenario):一系列步骤描述角色是怎样和系统交互,从而达到目标的
-
步骤(Step):描述每一步的交互(例如一套正常的ATM取款流程)
-
扩展场景(Extension):描述一些扩展的交互,例如一些意外情况(例如取款时账户余额不足)
下面将系统地介绍了使用Use Case的 原则
-
1. 通过讲简单的故事来传递信息
讲故事是最有效的人与人交流信息的途径,通过讲故事(Use Case),团队成员能对需求有统一的了解。当我们用自然语言讲故事的时候,我们不自觉地会把复杂的系统当作一个黑盒子,把重点放在用户的愿望、行动上面,这种做法非常有利于我们找到用户的需求和软件的功能点。当然,故事要包含具体的行动(Actionable),并且是可以验证的(Testable),所以讲故事也要有技巧 -
2. 保持对全系统的理解
虽然每一个用例都是一个简单的故事,但是不要忘了它是整个系统的一部分 -
3. 关注用户的价值
别迷失在长长的功能列表中,牢记软件的价值在于给用户提供价值 -
4. 逐步构建整个系统,一次完成一个用例
Ivar认为这是Use Case2.0方法论中最重要的一个观点。一个用例的完成可能要触及整个系统的各个层面(例如,“用户在ATM上完成跨银行的取款”这一用例需要银行系统各个子系统协同修改,才能完成),不同模块间复杂的依赖关系对团队是一个大的考验。 -
5. 增量开发,逐步构建整个系统
-
6. 适应团队不断变化的需求
User Case方法论的理念和敏捷、MSF大致相仿;它对细节的要求和典型人物、场景有很多相似之处。这些方法也有其 局限性:
-
故事/人物/场景非常适合交互式的系统,但是对于其他类型的需求(算法,速度,扩展性,安全性,以及和系统技术相关的需求)则不适用
-
故事的粒度没有统一的标准,和每个具体项目有关。初学者比较难以掌控
-
如果软件的关键在于用户体验的细节,那么如何把这些UI的细节嵌入每个故事中,并仍然保持故事的简明性是一个难题
有些团队把目前的技术扩展为Use Case Storyboard,当一个简明的故事加上很多附加说明和图画的时候,这事实上就成为了我们下面要提到的功能说明书(Functional Specification),以及下一章要提到的各种帮助建模的图形工具。
规格说明书
规格说明书(Specification)简称Spec,分为以下两种:
1. 软件功能说明书(Functional Spec),主要用来说明软件的外部功能和用户的交互情况(把软件当作一个黑盒子)
2. 软件技术说明书(Technical Spec),又叫设计文档(Design Doc),主要用来说明软件内部的设计规范(把软件当作一个透明的箱子)
功能说明书
功能说明书 从用户的角度描述软件产品的功能、输入、输出、界面、功能的边界问题、功能的效率(对用户而言)、国际化、本地化、异常情况等,不涉及软件内部的实现细节。
-
谁来写Spec通常是项目的PM,或者是有一定经验的开发或测试人员
-
谁来实现Spec开发人员、UX/UI设计人员
-
谁又来验证Spec是否全部实现了呢质量保障人员(QA),也可以由别的人员来实行,但是要注意必须从用户的角度出发来验证
-
怎么才能写好Spec实也不难,就是要把一件事情描述清楚
我们用一个例子来说明。如果你要给一个外星人描述地球人是怎么系鞋带的,同时,用英语写一份“系鞋带”的Spec,你会怎么写/p>
第一,定义好相关的概念
-
What is “shoe”, “shoe laces”, “tied shoe laces”,and “untied shoe
laces”(鞋、鞋带、系鞋带、解鞋带都是什么概念) -
Benefit of this feature “tie your shoe laces”(系好鞋带的好处是什么)
-
The goal of the feature(系鞋带的目标是什么),What does “success” look like(什么叫做“系好了”)
第二,规范好一些假设(Assumptions)
例如,鞋带是已经穿好在鞋上的么么样的鞋属于我们要处理的(拖鞋、凉鞋、球鞋、溜冰鞋、靴子)/p>
第四,描述主流的用户/软件交互步骤
用明确的步骤说明从“没系好”到“系好”的系鞋带过程
第五,一些好的功能还会有副作用
我们要把这些副作用明明白白地写出来。例如:美国很多地区用节能灯(LED)代替了原来的白炽灯,装在交通灯上。这一措施虽然节能,但是LED发热少,下雪天不能融化灯面的积雪,导致出现交通问题。当初的Spec务必要把这一副作用(危险)给写出来。
人民群众看不见具体的Spec,只能道听途说,其实专家有细致的解释

写好Spec的秘诀不多,只有下面三点:
实践,实践,再实践
1. Spec的最大敌人是什么乏味
软件公司的大部分人都不喜欢读文档,更不要说大学生了。强迫大学生写乏味和没有人读的文档,简直就是扼杀同学们对软件工程的兴趣。怎么才能把Spec写得让人读了不犯困呢/p>
-
用活生生的人物和故事描述用户是怎样用软件的
-
KISS(Keep It Simple, Stupid)——保持简单、直接的描述。涉及UI的部分可以直接上图,也可以画表格,不要写长篇累牍的文字。
-
如果是技术文档,最好把示例代码写上,单元测试也写好,让程序保证Spec的正确性,也让读者能够验证Spec的正确性。
-
把边界条件规定清楚,理工科思维的工程师们看到这里大脑就兴奋起来了——他们想找出你Spec的破绽!
2. Spec的另一个敌人是 时间。几乎在Spec写好的那一瞬间,Spec就开始过时了。容颜易老,Spec尤甚,怎么办/strong>
-
记录版本修订的时间和负责人——这样出了问题好去找人
-
在Spec中要说明如何验证关于功能的描述,从Spec的描述中就能知道单元测试该怎么写,最好把测试用例也链接上
-
把Spec和测试用例、项目任务等放在一起(例如放到TFS上),相互链接
-
变化是一定会发生的,与其在Spec中有意忽略这一点,不如主动挑明哪些部分是容易发生变化的,提前做好预案。说明哪些部分如果发生改变,会有何种连锁反应。
-
在做任何改动的时候,一定要事先参考Spec,事后更新Spec,团队领导人不应该在没有Spec 的情况下做拍脑袋的决定
功能说明书的模板
有 Spec的模板吗/strong>仿佛一旦搞到某个文档的模板、某课程的PPT,事情就成功了一半。盲目地套用最全面的模板,对项目有很大的副作用。PM对此尤其要注意。其实,把上面正反的例子综合起来,就是一个模板
-
Spec 的目标是什么pec 的目标 不包括什么/p>
Spec 的用户和典型场景是什么/p>
Spec 用到了哪些术语,他们的定义是什么/p>
用户是如何使用软件的功能的/p>
-
各种边界条件是什么、软件功能应该怎样随之变化——这些边界条件太多了:用户数量的变化,输入内容的上限和下限,不同国家/地区/文化/语言/硬件/软件版本/环境参数…
-
功能有什么副作用,对于其他功能有什么显性或隐性的依赖关系/p>
什么叫“好”,什么叫“这个功能测试完了,可以交付了”/p>
软件发布出去之后,有哪些和项目目标相关的数据可以收集,怎么在实现阶段就能把数据收集的工作准备好/p>
技术说明书
技术说明书又叫设计文档,它用于描述开发者如何去实现某一功能,或相互联系的一组功能。软件的功能多种多样,放之四海而皆准的模板是不太实用的,但是软件的设计总是要遵循一些规律,不遵循这些规律,工程师们往往在实现后面软件的演化中吃苦头。设计文档应该说明工程师的设计是如何体现下列原则的。
-
抽象(Abstraction)
-
内聚/耦合/模块化(Cohesion, Coupling,Modularization)
-
信息隐藏和封装(Information Hiding, Encap-sulation)
-
界面和实现的分离(Separation of Interface and Implementation)
-
如何处理错误情况(Error Handling)
-
程序模块对于运行环境、相关模块、输入输出参数有什么假设些假设和相关的人员验证过么
-
应对变化的灵活性(Adapt to Change)
例如,一个企业的流程管理软件,它能处理员工的各种请假需求,程序员会把每一种假期当作一个假期的子类(Sub Class)来处理。如果现在新增一个假期类型(例如“志愿服务者假期”),程序怎么变些设计要求工程师必须改源代码,添加子类,且在所有和假期相关的地方添加相应的处理,并要求所有管理软件都更新到最新版本。另一种做法是把所有的假期类型定义为数据,这样一来,新增一种假期类型时,只是数据增多了一项,相应的逻辑(也用数据表示)有一些变动而已。而源程序仍然保持不变。软件如何应对变化,是软件设计最重要的一个方面。 -
对大量数据的处理能力(Scalability)
如果数据量增大,程序还能保持高效率么/p>
功能驱动的设计
如何才能把用户的需求变成团队成员可以直接操作的开发工作,然后源源不断地实现这些需求能驱动的设计(Feature Driven Design,FDD)是针对这个问题的众多方法论之一。
FDD由下面几个步骤构成:
第一步:构造总体模型(Develop an Overall Model)
-
进入条件:团队已经选好了问题领域专家、主程序员、架构师。
-
任务1:决定建模小组成员,一般团队成员可以轮流参与
-
任务2:问题领域专家概要介绍问题领域知识。大家学习已有的参考资料(已有的建模文件、数据模型、功能需求、用户文档等)
-
任务3:以不超过3人的小团队构建子问题领域的模型,并在适当的时候补充总体模型
-
任务4:记录模型的信息并保存为文档
-
验证:和团队内部或外部的利益相关者验证模型以及它们对用户和业务活动的影响
-
出口条件:总体模型已经建好;各个实体(类)的关系也已经表达清楚,各个实体的属性和函数有初步定义;数据流、事件流程等说明文档已经完备
第二步:构造功能列表(Build a Feature List)
-
进入条件:团队已经选好了问题领域专家、主程序员、架构师
-
主要任务:构造功能列表
怎么表达一个“功能”DD认为,团队成员应该能在第一步工作的基础上,把问题领域描述的活动逐步细化,把大的问题领域分解为小的主题领域(Subject Area),然后描述在主题领域中出现的业务活动(Business Activities),最后细化和提炼出来的功能描述应该符合下列的三元组格式:
例如:计算此次销售的总额;验证用户的密码符合最低要求。
注:用英语表达功能时,大多数情况下 of 是很自然的表达方式,例如 Cal-culate the total of a sale,verify the password ofa user. 但是,同样的意思在中文里面会表达为<动作><实体>的<结果>,例如:计算此次销售的总额,验证用户的密码。同时,要注意团队成员估计一个功能所需的时间,如果时间超过两周,则需要再次细化。
- 验证和出口条件:此时团队应该得到:一系列主题领域、一系列业务活动、一系列功能,这些功能可以满足上面提到的每一个业务活动
第三步:制定开发计划(Plan by Feature)
在这一步,开发团队要根据下列因素制定开发计划:
-
各种实体和功能之间的依赖关系
-
实体和功能的复杂程度
-
高风险和高难度的功能要适当提前,这样能让大家早日看到结果
-
各位成员的忙闲程度
-
考虑对外承诺的演示/Alpha/Beta发布
验证和出口条件:经过这一步,团队就应该得到:
-
在每个里程碑中能实现的大致业务活动计划(精确到年/月)
-
主题领域完成时间(取决于最后一个功能的实现时间)
-
功能实现的先后次序
-
功能的相互依赖关系,和功能的所有者的对应关系
- 各个功能的复杂程度
第四步:功能设计阶段(Design by Feature)
在这个阶段,团队成员在主程序员的带领下,分析一组相关的实体及其功能,通过时序图(Se-quence Diagram)和其他工具,展示各个实体和函数如何动态地结合起来实现一个功能。通过这样的活动,团队成员就开始实现具体的实体和函数(使用面向对象语言的类/函数,或其他程序设计元素)。主程序员根据时序图和其他信息,更新实体模型。这一步产生的结果是:
-
“这次里程碑要发布的功能”文档,及其相关文档
-
各个业务活动对应的时序图,更新的实体模型,类/方法/属性
-
各位成员知道自己的功能实现计划,精确到天
第五步:实现具体功能(Build by Feature)
具体的团队成员要实现类/函数,进行相关的单元测试,并在代码复审之后,把代码集成到产品构建当中。这一步产生的结果是:一个完整的、验证过的功能。不同的方法论有各种适用范围,我认为,FDD适用于团队成员对于需求没有切身体会的情景,例如要实现不熟悉的行业(银行、证券、物流等)的业务系统。不过,我并未亲历过FDD的项目,仅从纸面上看,FDD 对单元测试之外的测试(如集成测试、压力测试、对用户界面和用户体验的测试)的讲述不足。如果软件团队在这些方面没有足够的投入,最终的系统会存在许多问题。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!