在网上看到说这个是讲用户故事非常经典的一本, 本着"张口闭口谈敏捷而不知道user story的程序人生是不完整的"的想法, 于是搜了来看看.
以前从没有接触过user story, 知道user case. 看过书之后, 绝大大部分情况下, 可以将二者等同起来看, 不过作者也讲到为什么user story不是user case, 指出了二者的不同, 不过可以将user story看成敏捷开发中的user case.
不过我不同意很多事情都只是口头交流, 而没有文档记录, 这在实际工作中是完全行不通的, 特别在人员流动性比较大的IT行业, 如果所有的知识都保存在熟悉某块业务和技术的少数人的脑袋里面, 这个是非常危险的.
========================我是读书笔记的分割线=======================
一旦任何一方在沟通中把持绝对地位, 项目就会遭受损失
如果业务方把持绝对地位, 他们就会关注软件功能和交付日期
如果开发人员把持绝对地位, 技术术语就会代替业务语言, 从而导致开发人员无法倾听业务方的实际需求.
不要在项目开始的时候做一套包罗万象的决策, 我们应该将决策分散到项目过程中.
我们要确保有一个获取信息的过程, 越早越好, 越频繁越好.
用户故事是用来描述对用户, 系统或者软件购买者有价值的功能.
3C(卡片, 对话和确认)
卡片代表客户需求而不是记录需求, 卡片包含故事的文字描述, 然而需求细节要在对话中获得, 并在确认部分得以记录.
多个小故事胜过一个庞大的故事
理想的情况是所写的故事能够让一两个程序员花半天到两周时间完成代码和测试.
如果一个故事太大, 我们称之为诗史故事.
并不需要不断分解故事, 直到有一个故事能覆盖每一个细节.
与其写下细节, 还不如让开发人员和客户讨论这些细节, 即在这些细节变得重要时才讨论.
在故事卡上加一些注释没有什么坏处, 但是关键还是讨论.
故事并不具有契约性质, 达成的协议由测试来记录, 这些测试将演示故事是否被正确开发.
故事卡背面的测试提示语句:
用空的工作描述试试
用很长的工作描述试试
用缺少薪资来试试
用六位数的薪资来试试
测试描述可以简短, 不完整, 可以在任何时候加入或者删除, 写这些测试描述的目的是传递故事的额外信息, 以便于开发人员知道故事于什么时候结束.
软件的客户和最终的用户应该在编写用户故事的时候承担着非常活跃的角色.
编写用户故事的过程最好从考虑系统的用户类别开始.
每个故事必须用商业语言来写, 而不是用技术术语.
用户故事强调对话交流而不是书面沟通
用户故事可以同时被你和开发人员理解
用户故事的大小适合于做计划.
用户故事适合于迭代开发
用户故事鼓励推迟考虑细节
用户故事的重点从文档转移到对话, 所以重要决策不会写到文档里面, 因为可能没有人阅读那些文档.
用户故事是一个非常合适的计划工具
故事是可以迭代的, 对于最终需要但当前不重要的特性, 可以先写一个大的诗史故事, 准备好将大故事加入系统后, 便可以提炼它, 抛弃诗史故事继而用更小的, 具体的故事代替.
~编写故事~
优秀故事的六个特点:
独立的
可讨论的
对用户有价值的
可估计的
小的
可测试的
如果分割的故事之间存在依赖, 有两种方式可以绕过这种依赖
将互相依赖的故事合并成一个大的, 独立的故事
用一个不同的方式去分割故事
如果我们在编写故事的过程中知道了一个重要的故事细节, 那么应该在故事卡上以注释的形式记录这些细节.
当故事卡上包含太多的细节, 这样会造成一种错觉:故事卡反应了所有细节, 没有必要跟客户进行进一步讨论
故事卡上的注释应该反应:
提醒开发人员要和客户进行对话
用来表明一些亟待解决的问题
在讨论中确定的细节将变成测试.
应当避免那些只对开发人员有价值的故事:
所有的数据库连接要通过一个连接池
所有的错误处理和记录应该在一系列公共类中完成
应该修改为:
这个应用软件, 最多50位用户使用一个5用户的数据库许可
所有的错误以统一的方式呈现给用户并做记录
三种情况会导致故事的工作量不可预估:
开发人员缺少领域知识
开发人员缺少技术知识
故事太大
一个不可以估计的故事最终会变成两个故事:
一个快速的探针故事(用来获得足够的信息)和一个故事(真正实现的功能)
合适的故事大小最终取决于团队, 它的容量以及所使用的技术
如果一个故事因为不确定性而复杂, 可以将它分成两个故事:一个做调研的故事和一个开发故事.例如"公司可以用信用卡支付发布职位的费用", 因为没有人做过信用卡相关的工作, 这个故事可以分成两个:
调查研究网络上处理信用卡的相关技术.
用户可以使用信用卡付费.
不可测试的故事发生在一些非功能性的需求上, 这些需求和软件相关, 但不直接与功能相关.
能自动化测试基本上比你认为的多的多.
~用户角色建模~
关于角色的定义, 坚持一个原则: 用户角色定义的是人, 而不是其他外部系统
给每一个角色定义一些特性来建立角色的模型
用户使用频率
用户相关领域知识水平
用户计算机和软件知识水平
用户对当前开发软件的熟悉程度
用户使用该软件的总体目标(便携性, 用户体验等)
即使我们承认无法为一个项目编写出所有的故事, 我们还是应该在早期尝试编写我们可以编写的故事. 即便许多故事还只能停留在十分笼统的阶段. 使用故事的好处之一就是可以用不同的详尽程度来编写
仅仅因为这些问题是用户提出的就认为只有用户才有资格提出解决方案, 这种观点是不对的.
某些时候, 需要使用非常具体的问题, 然而, 最好从背景无关的问题开始提问, 这样就有可能从用户那里获得更多样化的回答. 如果从非常具体的问题开始, 则可能漏掉很多故事.
在需要得到大量用户, 关于某些具体问题的回答时, 问卷是非常有用的.
在画原型的时候, 问一些有助于找到遗漏故事的问题:
用户接下来最有可能做什么?
用户会在这里犯什么错误
在这里, 用户会有什么困惑?
用户需要什么额外的信息?
验收测试也提供了确认故事是否被完整实现的基本标准. 有了这样的标准, 我们就知道什么时候某种事情算是做完了, 这是避免花太多或太少时间和精力的最好方法.
一般在下面这些时候写测试:
开发人员和客户讨论故事且需要记录明确的细节时
在迭代开始时, 在写代码前作为一项专门的任务.
在开发中或之后的任何时候发现新的测试时.
考虑每个故事, 然后问类似下面的一个故事:
关于这个故事, 程序员还需要知道什么?
对怎样实现这个故事, 我的想法是什么?
有没有一些特殊情况会使这个故事有不一样的行为?
这个故事在什么情况下会出错?
只要测试还在继续为故事增加价值和使它更加清晰, 客户就应该继续写测试.
~优秀故事准则~
当面临一个大的故事时, 通常有许多方法可以将它分解成较小的故事, 许多开发人员首先想到的是将故事按照技术线路分割. 而每个故事应该提供某种程度上的完整功能.
在开发中及早涉及软件应用程序框架的每一层能够有效降低最后时刻才发现层次架构方面问题的风险. 其次, 尽管不完美, 即使只提供部分功能, 但只要发布的功能可以跑, 就可以放心把应用发布给用户使用.
如果项目团队已经识别出用户角色, 那么在编写故事时就要使用它们, 所以不要写成"用户可以发布他们的简历", 而要写成"求职者可以发布他们的简历".
当故事只为单一用户编写时, 故事的可读性是最强的.
用户故事用主动语态编写, 更易于阅读和理解. 例如, 要说"求职者可以发布简历", 而不要说"简历可以被求职者发布"
故事卡的主要目的是用来提醒开发人员和客户团队对功能进行讨论.
为了确定故事, 从每个用户角色使用系统的目标开始考虑.
为团队即将实现的功能编写小的故事, 针对未来实现的功能编写宽泛的, 高层次的故事.
用户故事要简单, 别忘了, 他们的目的是为了提醒开发人员和客户进行对话.
没有必要理解故事的所有细节, 过分地深入每个故事的细节会让会议变得冗长, 低效.
故事是对用户或客户有价值的功能的描述, 它们并不是开发人员的代办事项.
敏捷没有前期设计阶段, 敏捷过程的特点是做频繁的短期设计.
从故事中分解出任务的例子, 假设有一个故事"用户根据不同的字段搜索酒店", 可以编写下列任务:
编写基本搜索界面
编写高级搜索界面
编写搜索结果页面
为支持基本搜索查询数据库编写调试SQL语句
为支持高级搜索查询数据库编写调试SQL语句
在帮助系统和用户指南里写下新功能的文档
~故事不是什么~
故事与用例之间最明显的区别是它们的范围, 二者的大小都是以交付商业价值为目标, 但故事的范围更小, 因为我们对它们的大小有限制(不超过10个开发工作日), 以便安排工作. 用例覆盖的范围几乎总比故事大.
用户故事和用例的不同还在于他们的完整性. 故事卡上的文档加上验收测试基本相当于用例. 即故事对应用例的主要成功场景, 而故事测试对应于用例扩展.
用例和故事之间的另一个更重要的区别是它们的寿命. 只要产品在开发或维护, 用例常常作为永久性的工件持续存在. 另一方面, 故事不会超过包含他们的迭代. 虽然可以对故事卡存档.
另一个主要的区别是用例比较容易包括用户界面的细节.
用例一般写成分析活动的结果. 用户故事则写成注释, 用以启动分析谈话.
~用户故事的优势~
用户故事的目的并不是让我们事无巨细记录下想要的特性; 相反, 用户故事作为提示语句提醒开发人员在将来需要与客户进行沟通与交谈.
在开始编码前, 我们并不需要写出所有的用户故事, 可以写出一部分故事, 就进行编码与测试, 然后按需要的节奏重复这个过程. 写故事时, 我们可以按照合适的力度去写.
例如在开始考虑一个项目时, 写出一个诗史故事"用户可以撰写并发送电子邮件", 对于早期计划有用, 后来我们可以把该故事分割成一打新的故事:
用户可以撰写邮件
用户可以在邮件中包含图片
用户可以发送邮件消息
用户可以设定邮件发送的一个具体时间.
用户故事提醒我们用随机应变的方式开发软件
把交谈的重点从一个系统的特性转移到描绘用户使用该系统目标的各个故事.
用户故事是一个吸引用户参与设计他们所需软件的便捷手段.
源于面对面的沟通, 故事能够促进团队内隐性知识的积累.
尽量保持用户故事不要过于细节化, 知道团队开发这些故事时才开始细化
~用户故事不良征兆~
如果两个故事在很大程度上共享同一份实现, 实现一个故事, 只需要再花很短的时间就可以实现第二个故事, 在做计划的时候应该将两个故事合并起来.
如果觉得故事过小, 解决方案很简单, 就把互相依赖的故事合并成一个故事.
好的故事应该包含整个系统各个层面的功能.
敏捷团队客户的参与度往往非常高. 每天客户都会与团队有密切的交流, 因此很难给客户带来较大的惊喜
如果项目组中的开发人员花太多精力去开发镀金功能, 一个有效的解决方法是提高项目组中每个人的任务可见性.
把故事写在小卡片上的一个好处是在小卡片上只能记录很有限的东西.
如果在故事中包含太多的细节, 说明团队过于重视文档, 而忽视口头交流.
如果总是需要写满小卡片, 那么下一次就用更小的卡片
利用用户故事的关键在于承认事先不可能发现所有的需求.
如果客户很难给故事安排优先级, 第一个可能的原因是故事太大.
~scrum与用户故事~
如果需要完成测试任务, 但是没有空余的测试人员, 其他的开发人员也会参与测试. 大家共同负责结果
scrum团队中通常没有区分架构师和测试人员角色的说法, 团队根据实际情况, 自决怎么完成剩余的任务.
ScrumMaster更多的是为Scrum团队服务. 而不是指手画脚, ScrumMaster主要负责为团队排除障碍, 保证开发的顺利进行, 确保整个团队按照Scrum的简单规则进行开发.
在项目初期, 一般不需要投入很大的精力写出所有的功能. 通常, 产品负责人和团队一起写下一些比较显而易见的功能.
在每个sprint的开始是sprint计划会议. 这个会议通常会持续一整天.
在sprint计划会议的前半段, 产品负责人会把待开发的高优先级的功能介绍给scrum团队, 在第二个阶段, 团队成员可以针对第一个阶段中介绍的每一个待开发功能提出问题, 如果团队有信心完成某一个功能, 就把这个功能从产品Backlog移到sprint backlog中.
在sprint结束时的评审会议上, 团队会审视自己是否达到了spirnt目标, 而不是太关注上一个sprint中完成的每一个具体条目.
一旦sprint开始, 只有团队成员才能向sprint中添加工作.
团队从产品backlog中选择故事之后, 会从故事中划分出任务, 形成sprint backlog.
不要让团队觉得sprint评审会议是一种干扰或者负担, 它应该是sprint自然而然的结果.
每日晨会的一个重要目的是让每一个成员在自己和同事面前做出承诺, 这个承诺不是向经理或者公司的承诺, 而是团队成员之间的承诺.
不要让每日晨会演变成一个讨论系统设计或者解决问题的会议, 一些问题会被记录下来稍后解决. 不要在每日例会上解决问题.
ScrumMaster必须保持每日例会的快节奏, 确保所有人只回答三个问题.
scrum不要求也不建议一开始就维护很大的产品backlog.
一开始不要求产品负责人确定所有的需求, 但是尽可能多的记录故事还是有一定好处的.
用户故事有一个好处就是作为一个提醒, 团队始终明确要做什么, 幕后的动机是什么.
~其他话题~
大多数项目一般都会有一部分需求无法恰当地以故事的形式来表达, 这些往往是系统的非功能性需求.
非功能性需求:
性能
准确性
可移植性
可重用性
可维护性
可用性
易用性
安全性
容量
许多非功能性需求可以视为系统行为的约束.
处理约束的最好办法是在卡片上写下约束, 并将卡片标注为"约束"卡. 大多数情况下, 编写自动化测试可以确保系统遵守约束.
卡片相对于软件工具的主要优点之一就是他们的技术含量低的本质, 可以不断提醒人们故事是不精确的.
在某些情况下, 非常重要的故事会因为代价过高也会变得不那么重要.