中小企业团队敏捷产品开发流程最佳实践

近期因为疫情的影响,不少互联网公司开始尝试远程工作。也出不了少如何做好远程工作的方法,我认为不管是场地办公还是远程办公都依赖于原来的产品开发流程。

我曾经遵循CMMI5的流程管理过15人左右的跨国/语言/文化团队,也遵循敏捷Scrum管理过9人的小团队,还针对一个从4人发展到近30人的团队尝试过各种方式的项目管理方法,这其中有2C和2B的产品,也有平台/生态型产品。 最后在自己创立公司的5人小团队(场地和远程办公融合方式)中摸索出了我认为最适合中小企业产品开发流程与管理方法。

今天我们聊聊产品开发流程与管理。我们通过对Scrum的改造,利用Gitlab的issue对需求、开发和测试进行可视化管理。应该来说能够适应绝大多数的中小企业和团队,当然再好的流程也会因不同的人来落地执行而产生不一样的效果。

定义产品 

首先我们要确定开发的是产品,而非项目。产品和项目的区别是什么?与此对应的另外一个问题是产品经理和项目经理的区别是什么? 后面的问题我们不在此篇中讨论,产品和项目的区别主要在两方面体现:生存周期和目标。

项目的生存周期比较短从启动、策划、执行、监控到收尾。验收交付给用户之后项目就结束了。而产品不存在结束的说法,因为产品是不断更新的,直到被新产品替代,生存周期才结束。 

项目的目标是在规定的时间内,利用有限的资源,高质量的完成某个特定用户的需求。而产品更多是为了满足一些用户的通过用需求。

当然项目和产品之前存在很多的关联,如果产品按迭代开发,每个迭代有时候像极了一个项目。项目和产品有时候是协同发展的。

中小公司团队

我们这个流程更适合小公司和团队,但是中型的公司如果资源比较紧张的时候也适用。小团队的特点通常是可能没有专职的UI设计(或者比较少)、没有专职测试人员 (或者比较少)。没有那么规范的管理流程,有人身兼多职。所有该流程的目标是希望追求高效的团队产出同时兼顾产品的长期发展。

敏捷开发流程对产品开发的影响

产品开发成什么样是由产品经理设计的,能不能满足用户的需求,会不会给公司带来利润很大程度上都依赖于产品经理。俗话说把所有的宝都押在一个人身上是很危险的,因为产品本身需要满足的是一群人的需求,以及产品经理对需求的挖掘和理解各有差异,敏捷开发很大的一个出发点是通过延迟设计和实现来规避这个风险。

MVP(最小可行性产品)的思路来自于《精益创业 》 

敏捷开发中“迭代iteration"的思路跟MVP的思路基本一致,我们在进行敏捷开发中很重要的环节不是你的流程执行的对不对,而是迭代需求有没有拆分好,否则不可能在用户那边过关。 这个重点环节需要Master和PO(Product Owner) 以及技术Leader一起来完成。

不能按开发任务的整体性来安排迭代任务,这里的标准是:每一个迭代完成之后应该交付给用户完整可用的产品。对于2B,特别是大B用户类的产品,迭代周期可以长一些,多预留一些测试时间,待产品足够稳定之后再上线。

UserStory需求优先级评估

一个UserStory是一个完整的用户需求,结合自身团队的情况以及需求的难易程度可以在每次迭代计划会议的时候来确定下个迭代要开发哪些UserStory。这其中团队需要对如何挑选UserStory有一个明确的定义。

我们采用 KANO模型法(基本型需求> 期望型需求>兴奋型需求 ) + 满足核心业务的投入产出比最大的需求优先(ROI最大化) 组合评估。

在KANO的基础上优先处理基本需求(也可以称之为核需求),在核心需求依然很多需要排序的时候采用核心需求投入产出比最大化原则进行排序 。

P0-N,P1-N, P2-N 

  • P0为基本核心需求

  • P1为期望型需求

  • P2为兴奋型需求

N为ROI评估,为1到5数字,5的ROI最大,得此组合6永远优先做P0-5的需求。ROI的评估大抵是以研发投入为成本,用户价值和公司价值作为回报来评估。

希望各位开发人员以后机智一点,不要直接跟产品说这个需求做不了。而是问:“你这个需求为用户带来了什么?给公司带来了什么?” 

改良版Scrum

Feature/UserStory- 用户需求(我们团队叫Feature是受历史遗留影响)

Task - 开发任务

Bug - 缺陷 

角色

  • Master  

  • Product Owner

  • Developer

  • Tester

角色职责 

Master

  • 保证Scrum流程的正确执行,以及以下会议的纪律 

  • 迭代计划会议

  • 每日站会

  • 迭代回顾会议 

Product Owner

  • 清晰定义每一个UserStory,确保 DevOwn以及测试对UserStory的正确理解

  • 定义UserStory优先级

  • 同步 UserStory文档及原型的变更 

  • 确保 UserStory 得到拆分以及执行(Project Management项目管理)

  • 验收 UserStory  

Dev

  • 作为Dev Owner 正确理解需求,从技术和实现角度与PM沟通需求,协助改进需求

  • 将UserStory拆分为Task 

  • 将开发代码的合并请求关联到Task 

Tester 

  • 正确理解需求,从测试和用户体验角度与PM沟通需求,协助改进需求 

  • 测试UserStory与Bug管理 

  • 验证Bug

目标(以企业能够承担得起的成本来做可持续发展):

  • 用好文档:重要的文档一定要有

  • 高效协作 :可以用文档沟通的方式,就不要开会 

  • 实用主义:不要花太多时间写测试用例

  • 培养团队: 在允许的范围内充分授权团队自己决策与执行,TL与管理者应该更多地辅导。

定义:

  • UserStory: 只是一句话的需求描述什么角色需要什么样的功能,并不是详细的功能设计。

  • 架构方案设计: 指的是那些重大的框架性的调整,需要有人专门设计和开发好之后其它开发人员才可以在此基础之上开发。属于基础建设之类的,比如:开发框架,消息队列处理之类的通用组件和功能。TL要评估这个事情能不做的就留着给DevOwner去做,TL进行辅导。

  • 产品原型:只包含本迭代内的UserStory的详细设计

  • 测试用例:并不是非常详细的测试用例,更像是check list

  • DevOwner: 每一个UserStory会分配一个DevOwner,通常是自己主动承担的,会比Dev多一些项目管理的职责。可以培训开发人员的项目管理能力,但是需要Leader或者Manager来给予辅导 。

主要流程

  1. PO 定义UserStory 放入Catelog 需求池(只有有这个想法了,或者用户提出来了就放到需求池。

  2. 提前一个迭代对UserStory 进行排序,计划下一个迭代的UserStory。

  3. 开发测试在做本迭代开发任务的时候 ,产品经理进行下一个迭代的产品详细设计

  4. 产品的详细设计出来之后,直接将文档发给整个团队进行线下阅读。TL和测试分别进行技术架构方案和测试用例的编写。

  5. 技术方案和测试用例的评审可以是通过文档线下来进行(不需要开会)

  6. 产品原型的评审也是可以由线下进行不开会。

  7. 组织迭代计划会议,可以提产品原型中的问题。给每个UserStory分配好DevOwner

  8. DevOwner线下拆分Task,TL离线异步评审

  9. Tester 测试UserStory填写bug 

  10. Dev 修复 bug 进入Bug管理流程

必须要开的会议只有一个迭代规划会议、每日站会、迭代回顾会议。其它的会议尽量通过文档的形式离线解决。

与主流Scrum的主要差异         

  • 需求UserStory的StoryPoint由技术Leader一个人给出即可,主要用来大致评估成本,开发的Task是由开发人员自己按小时评估工时。(Scrum建议都按StoryPoint来估)

  • 给UserStory 排优先级的时候不需要团队所有人员参与,多数情况是产品经理和技术Leader决定就可以了 (Scrum建议团队所有人员在估算会议一起参加) 

  • 添加了产品详细设计与测试用例设计和评审的过程(优先鼓励通过文档异步的方式来评审)

  • 评审/演示会议由产品经理示情况进行线下验收还是在会议上由开发自己来演示 

  • 用gitlab issue来做可视化管理 

  • 单独对Bug管理的流程进行了补充定义 

可视化管理

敏捷开发中非常强调公开、透明、直接有效的沟通,这也是“白板”在敏捷开发中如此重要的原因之一。通过“白板”让所有人直观的看到所有任务的状态、问题、以及任务之间的流动 。当然用白板和便利贴来管理任务会更有趣,但不是每个团队都能玩好。工具是给人用的,只要抓住背后的核心诉求,大多数的工具都能达到效果。

我之前用的是Teambition来做的可视化管理,现在的公司使用Gitlab Issue功能(它跟开发的代码评审结合的更紧密)所以我利用issue管理的功能和它的Board,Milesontes和 Labels功能结合起来就可以很好的对UserStory,Task和Bug来进行管理 。

以下我们创建UserStory,Task,Bug在Gitlab里面都是issue,只是我们打上了不同的标签。 

需求池

单独新建一个需求池的Board把所有包含Feature(UserStory) 的标签列出来。这里Doing就当前迭代的需求,ToDo是下个迭代的需求。Open是所有待完成的需求。 

UserStory

需求由产品经理创建之后将相关的一些文档和原型地址都全部汇总到描述中,如果需求有变更需要同步更新。

  • 在迭代会议的时候指定开发负责人DevOwner

  • 由DevOwner对需求进行进一步的详细分析之后拆分任务并创建Related Issue,并指派具体的开发人员

Task

开发的任务中关联了对应的UserStory和相关的代码commit、merge request等。通过开发任务就可以直接找到与这个任务相关的代码。

燃尽图

Scrum在给所有的task打上StoryPoint之后,根据每天剩余(未完成任务)StoryPoint的总和绘制图表就得到了燃尽图。

理想的燃尽图应该是像下图中的虚线那样规律性的下降直到0(所有任务开发完成),通过这个图就可以看到在这个迭代内任务被关闭的情况,用来分析开发团队的实际产出。

Bug缺陷管理 

传统的开发-测试流程造成了很多问题:开发写完代码之后对自己的任务甚至不做基本的检测就丢给测试。测试也没有精力去做一些自动化的工作。中间测试-开发还常常出现推诿,反复的情况。 开发也没有机会去加强自己的测试sense和技能。最后只能造成双输的局面。

理想丰满,现实骨感

Scrum以及敏捷开发提出来依靠测试驱动,自动化单元测试、集成测试来达到内建质量的提倡当然是非常好的。但是国内大多数中小团队都达到不这样的条件这样做。我们只能退而求其次,在满足用户要求的产品质量的基础之后,逐渐培养开发人员的测试能力以及测试人员自动化脚本能力。

建立和持续改进机制

我们现在10个人的团队中有一个测试人员来建立和巩固基础测试流程、维护通用测试用例、 对开发人员对于测试技能培训、 以及进行迭代bug回顾和观测来达到持续改进的目的。

基础测试流程

基础测试流程与传统的测试流程大致相同,这里主要的变化是将测试用例写的足够简单以便于让开发理解和快速校验。我们在开发提交功能给测试之前需要自己先走一遍测试之前提供的该功能的用例确保每一项是通过的。 保证你写的代码能运行正常是每一个负责任程序员的基本素质。 

测试人员从一开始就深度参与到这个迭代开发的每一个环节,加上对于开发任务的可视化管理。测试在打开bug的时候直接assign给对应的开发人员。不需要leader再额外的approval。

标签管理

以下是在gitlab labels中额外添加的一些标签用来在后面迭代回顾的时候更好地统计bug进行质量改进分析。

  • Priority 优先级 

    • High

    • Medium

    • Low

  • Severity  严重级别 

    • Critical 致命

    • Major 高

    • Minor 中 

    • Low 低

  • Resolutions 关闭原因

    • Fixed 最后确认是bug并且修复了

    • Deferred 是bug,但是延期再修复 

    • Duuplicate 重复了

    • As Designed 设计就是这样,不是我的锅 

    • Cannot Reproduce 不能重现 

这些标签可以可通过gitlab 的scoped标签(父标签::子标签)的形式来管理,比如Priority::High, Prioirty::Medium, Priority::Low。

测试用例

我们的测试用例与标准的测试用例有很大的区别,基本上我们是不写测试步骤的。只写简单的用例描述和预期结果,当然这个预期结果会尽量包含所有的分支。开发人员需要在提交测试之前自己确保这些功能都是正常的,否则我们会定义为严重的不负责任。

Bug回顾 

没有回顾就没有持续的改进 。在每一个迭代结束之后,我们都要将这个迭代产生的bug进行统计汇总、团队一起分析,并与之前的迭代bug统计进行对比。gitlab没有比较方便的统计图表功能,所以我们会把有bugs标签的issue导出到excel再进行分析。

按严重级别进行汇总

按人员进行汇总

按关闭原因进行汇总

常见问题总结

通过加强开发自测试和建立持续改进机制我们逐渐让测试人员有一些时间从质量管理更宏观的层面去做改进,也让测试有一些时间去建立自动化体系。

结语

流程只是整个产品开发管理中很小的一部分。流程为人服务,而不应该是徒添负担。 除了流程,我们还需要建立完善的团队奖惩机制、员工培训和晋升机制,整个团队才会有活力。由于篇符有限,可能有些地方会有遗漏,还请各位海涵!

图书推荐

如果大家想对Scrum和敏捷开发有更多的了解,有兴趣的同学可以看看下面两本书。我在上篇文章说建议大家多学一些除了代码之外的东西。我是个说到做到的人。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/311902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构---二叉线索树

数据结构—二叉线索树 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> typedef struct bmTree {int data;struct bmTree* lchild, *rchild;int ltag, rtag; }bmTree; bmTree * preNULL;//中序遍历的前驱指针 void cr…

revit如何根据坐标进行画线_铭成教你如何根据同步带的齿形进行选型

1、同步带齿形分类梯型齿同步带分为&#xff1a;最轻型MXL、超轻型XXL、特轻型XL、轻型L、重型H、特重型XH、超重型XXH&#xff0c;共七种&#xff0c;这几种是目前市场用的最广泛的。特殊齿型的同步带又分为&#xff1a;最轻型T2.5、轻型T5、重型T10、最重型T20&#xff0c;现…

在VS Code里逛知乎、发文章?知乎 on VS Code来啦!重新定义内容创作!

本文为 牛岱 的原创文章在2020年2月10日首发于“玩转VS Code”知乎专栏你是否已经厌倦了知乎 Web 端文本编辑器糟糕的使用体验和时而出现的奇怪 Bug&#xff1f;身为程序员的你是否想用你最熟悉的 Markdown 语法写答案&#xff0c;并且获得最佳的代码块语法高亮&#xff1f;攥写…

线性代数---向量问题的求解方法

线性代数—向量问题的求解方法 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

java 定时_Java线上定时任务不定期挂掉问题分析

作者&#xff1a;IKNOW本尊问题背景收到频繁的告警邮件&#xff0c;定时任务调度失败&#xff0c;查看xxl-job的执行器列表是空的&#xff0c;但是服务又显示健康&#xff0c;查看历史任务执行记录发现执行器是依次递减&#xff0c;由于是线上服务&#xff0c;只能先重启&#…

gRPC in ASP.NET Core 3.x -- Protocol Buffer, Go语言的例子(上)

前两篇文章半年前写的&#xff1a;gRPC in ASP.NET Core 3.0 -- Protocol Buffer&#xff08;1&#xff09;&#xff0c;gRPC in ASP.NET Core 3.0 -- Protocol Buffer&#xff08;2&#xff09;之前把protocol buffer的基础知识讲了一遍&#xff0c;今天使用Go语言做一些例子。…

word List 11

word List 11 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

温故知新 .Net重定向深度分析

在早期的.NET Framework程序员心里&#xff0c;重定向Redirect其实分为两种&#xff1a;Response.Redirect&#xff1a;Response对象的Redirect方法提供了一种实现客户端重定向的方法Server.Transfer&#xff1a;Server对象的Transfer方法使用服务器执行重定向&#xff0c;并避…

笔记本电脑销量排名_网友总结京东笔记本销量,联想高居第一,华为表现很出色...

笔记本电脑&#xff0c;还是要看大品牌。网友总结近30天京东笔记本销量&#xff0c;结局让人出乎意料。网友直呼&#xff0c;原来华为笔记本这么强。智能手机的出现&#xff0c;对传统的PC行业造成了一定的影响&#xff0c;但它始终还是无法替代PC的功能。在这个行业中&#xf…

数据结构---二叉排序树

数据结构—二叉排序树 原理&#xff1a;参考趣学数据结构 代码&#xff1a; #include<stdio.h> #include<stdlib.h> typedef struct bstTree {int data;struct bstTree* lchild, *rchild; }bstTree; void createBSTTree(bstTree* & T,int data) {//创建二叉…

研发协同平台持续集成2.0架构演进

在上篇《研发协同平台持续集成实践》一文中我们分享了为什么要做持续集成&#xff0c;技术选型&#xff0c;工作原理以及实践落地。今天我们从架构上来分享一下架构层面的设计和演进。持续集成1.0在最开始设计的过程中&#xff0c;本着一切从需求出发&#xff0c;一切以实现业务…

口袋操作系统_全自动阀口袋包装机的发展

随着全球产业技术的不断发展&#xff0c;包装机行业也出现了产业结构调整的动向&#xff0c;因为全新的全自动阀口袋包装机和全新的包装产品技术问世&#xff0c;那些制作粗糙&#xff0c;能源消耗大&#xff0c;技术相对比较落后的阀口袋包装机也将会被市场一步步淘汰掉&#…

数据结构---二叉搜索树

数据结构—二叉搜索树 原理&#xff1a;参考趣学数据结构 代码&#xff1a; 队列代码&#xff1a; #pragma once #define N 100 #define elemType bstTree* #include<stdlib.h> typedef struct bstTree {int data;struct bstTree* lchild, *rchild; }bstTree; typede…

《ASP.NET Core 微服务实战》-- 读书笔记(第10章)

第 10 章 应用和微服务安全云应用意味着应用运行所在的基础设施无法掌控&#xff0c;因此安全不能再等到事后再考虑&#xff0c;也不能只是检查清单上毫无意义的复选框由于安全与云原生应用密切相关&#xff0c;本章将讨论安全话题&#xff0c;并用示例演示几种保障 ASP.NET Co…

里加一列为1_9月1号新宠物食品法规实施啦,辣鸡宠物食品遭殃,你也可能违法...

大家好啊&#xff0c;今天是2019年9月1号&#xff0c;对于宠物行业其实是一个非常特别的日子今天宠物饲料管理办法正式实施加上2019年1月1号实施的宠物饲料卫生规定以及2015年3月8号实施的全价宠物食品 犬粮&#xff0c;猫粮标准中国的所有的猫狗宠物食品在今天有法可依&#x…

[蓝桥杯2016初赛]凑算式-dfs,next_permutation

代码如下&#xff1a; #include <iostream> using namespace std; const int N 15; bool st[N]; double a[N];int cnt; void dfs(int u) {if (u 10) {if (a[1] a[2] / a[3] (a[4] * 100 a[5] * 10 a[6]) / (a[7] * 100 a[8] * 10 a[9]) 10) {cnt;}}for (int i …

word List 12

word List 12 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;

软硬件协同编程 - C#玩转CPU高速缓存(附示例)

写在前面好久没有写博客了&#xff0c;一直在不断地探索响应式DDD&#xff0c;又get到了很多新知识&#xff0c;解惑了很多老问题&#xff0c;最近读了Martin Fowler大师一篇非常精彩的博客The LMAX Architecture&#xff0c;里面有一个术语Mechanical Sympathy&#xff0c;姑且…

python操作excel_使用Python操作Excel时必学的3个库

Python对Excel的操作我主要用xlwt、xlrd、xlutils这三个库。1、xlwt主要用来创建并写入数据到Excel。已经存在的表不可以写入。以下使用Python写九九乘法表到Excel运行之后&#xff0c;代码文件所在的文件夹会多出一个”九九乘法表“的Excel&#xff0c;内容如下图&#xff1a;…

线性代数---线性方程组

线性代数—线性方程组 常见题型的解题技巧 如果存在什么问题&#xff0c;欢迎批评指正&#xff01;谢谢&#xff01;