【视频】由接力赛跑学习组织管理

一直以来大家都关注于生产力(productivity),但由于过往对于效率的基本认识,导致组织或管理的效率上的努力适得其反。被视为经典的效率三位一体(trinity)指的是:清晰(Clarity),度量(Measurement)和问责(Accountability),恰恰是它们使人们的努力白费。 我们可以通过接力赛跑来看待以及证明这个观点。世界杯女子接力赛决赛一共有8支队伍。最快的是美国队,美国拥有全世界最快的女运动员,是夺冠热门。如何拿她们和其他队伍比较,比如法国队。 按照她们在100米短跑当中的最佳成绩,把美国选手个人的成绩相加起来,最后她们会在达终点线时比法国队领先3.2米。今年,美国队状态很好。根据她们今年的最好成绩,她们在到达终点时应该要领先法国队6.4米,这是根据数据推算的。美国队第四棒Torri Edwards今年在100米赛跑中获得了金牌。美国队第二棒Chryste Gaines是地球上跑得最快的女性。显然,美国队赢得了人才争夺战。不过在其背后,普通的队伍也在奋力追赶。 视频里发生了什么?最快的队伍没有赢,慢的那一队反而赢了。 为什么呢? 因为合作。你可能听过这句话:“多亏了合作,整体大于部分之和。”这不是诗歌,这不是哲学,这是数学。握着接力棒的人跑得慢了点,但她们交接棒更快。合作的奇迹能让人们努力的能量和智慧加倍。这是人们努力的精髓:我们如何合作,个人的成果如何为团队做贡献。通过合作,我们可以事半功倍。 那么,当圣神三位一体(清晰、衡量、问责)出现时,会对合作产生什么影响? 清晰 管理报告充满了对缺乏清晰度的抱怨。 合规性审核、咨询诊断。我们需要更高的清晰度,我们要明确角色和流程。就好比说队伍里的选手说,“我们明确下吧:我从哪里跑到哪里?我要跑95米,还是96、97米...?”这很重要,我们要分清楚。如果你说97米的话,那么跑完97米,人们就会把交接棒丢掉,可不管到时候有没有人接。 想想软件开发过程中,我们也经常听到类似的,“我是做开发的,测试我不管”,“这是后端处理的,等他们做好了再说”,“现在是运维的事情了”。我们对软件开发过程中的各种行为进行了分类,并指定一个角色。整个开发过程要有清晰的阶段,角色的职责边界也要十分清晰。那么,不清晰可以有什么选择?比较常见的情况是我们按照职能,开发流程,系统组件来划分角色职责,比如开发可不可以做些测试,和测试人员一起协作共同为质量负责,前端开发和后端开发互相协作共同为交付功能负责。模糊掉组件间、职能间的边界,把他们都放入一个团队共同为交付特性负责,形成特性团队。 问责 我们总是试图把责任规定给某个人。谁对这个过程负责?我们需要一个人对这个过程负责。所以在接力赛中,既然交接棒如此之重要,那么我们需要非常明确负责交接棒的人是谁。在两个选手中间,我们现在要规定一个新的专门的运动员,这个运动员要非常明确地专注于接过上一个选手的交接棒,然后再交接给下一个选手。而且我们至少需要两个这样的选手。那么,这样还会赢得比赛吗? 这个我就不知道了,但是可以肯定的是,我们有一个明确的分工,对责任有了非常明确的划分界线。我们会知道由谁来承担过错。但我们不会赢得比赛。如果你仔细想想,会发现我们时把更多精力集中在失败的时候确定谁来负责的问题上,而不是去创造有利于成功的条件。把所有的人类智慧都投入到组织设计(城市结构、处理系统)当中真正的目的是什么?目的是在失败的时候把责任归咎于某人。我们创造了会失败的组织,但是以一种合规的方式来创造的,在这种组织中,有明确的人来为失败负责。在失败这点上,人们做的相当有效率。 软件开发过程中,好像还真会出现负责交接棒的人,比如技术Leader或者项目经理,帮助协调组件间的调用,协调不同人或者团队间的工作安排等。至于问责,呵呵,大家都懂的,老板需要个出了事能骂的人。这确实是更多的考虑失败的情况,那怎么创造成功的条件呢?其实很多时候真正有效协调的人,恰恰是具体做事的人。但如果这样协调没有发生,那是不是因为大家不知道有东西需要协调?我们可以提供足够的信息让大家了解互相之间的工作安排,比如做联合的计划会议或者需求讨论。或者建立机制让大家及早的发现工作间的冲突,比如使用持续集成。 度量 东西度量好了,事情也就完成了。你看,要传递交接棒,你要在对的时间、用对的手、以正确的速度来传递。但要这么做的话,你要把能量分配到你的手臂里。你手臂中的能量不在你的腿里。你必须牺牲掉可被衡量的速度。你将要交接的时候要及早喊出声,发出信号说明你快到了,以便让下一位选手有所预备。而且你要喊得够大声。但是这时血液、能量会集中在你的喉咙里,而不是你的腿里。 因为你知道,这时候有8个人同时在喊。 所以你要辨别得出你队友的声音。 你可不能说,“是你吗?”这就晚了! 大家注意第三棒选手。你看她把力量、能量和注意力 都分配在哪里。并没有都在腿部,虽然这样对她的速度很有利,可也分配在了喉咙、 手臂、眼睛、大脑里。那么这对哪个选手的腿产生了影响呢?答案是下一个选手的腿。但当下一名选手跑得特别快的时候,这是因为她自己特别使劲跑了呢,还是因为前面一名选手的交接棒传得好呢?这个地球上没有标准来给我们一个答案。如果我们根据可以测量的表现来对人们进行奖励的话,人们就会把自己的能量、注意力和血液集中在能够被测量的部位:腿部。而这样一来交接棒会滑落然后传递速度会减慢。 合作不是一股超级力量,而是对力量的分配。这意味着冒险,因为你要牺牲可被客观测量的个人表现所能给予你的终极保障。这对别人的表现有着重要影响,而这些人正是和我们相比较的人。所以要合作就要当傻子。但是人们可不是傻子,所以他们不合作。 度量是个老生常谈的问题了。我们设置度量指标的时候,需要想一想到底我们要这个指标达成什么目的?我们对这个指标有什么预期?(达到某个值,或是出现某种趋势等)如果这个指标达成预期了,我们会采取哪些行动?如果这个指标没有达到预期,我们又可以采取哪些行动?为什么这些行动现在没有发生? 我们常见的许多度量让我们过于关注于某些局部,未必促成最终结果的改善。如果使用度量,度量是否加强合作,还是让大家各自为战?有的组织十分依赖KPI,给开发人员设置的KPI要求他们产生的Bug要少,给测试人员设置的KPI要求他们发现的Bug要多,你觉得这些开发人员和测试人员合作的可能性有多大? 你知道吗,在比较简单的世界里, 清晰度、问责制、度量都是可行的。 但商业已经变得更加复杂了。如今要吸引并留住客户,打造世界级的优势并创造价值,是一件要求严苛的事。而商业越是复杂,我们就越是会以清晰度、问责和衡量的名义来让结构、过程和体制更加繁杂。 要知道,这种对清晰度和问责的推崇会引发一种反生产力的复杂化,导致出现更多的分界线、中间部门、协调者,他们不仅能动员人力和物资,但也会增添障碍。组织越是复杂,就越难理解究竟发生了什么。所以我们需要做总结、代理、报告、关键绩效指标、度量标准。所以人们都把精力放在了可以被测量的东西上,然后牺牲合作。当表现退步了,我们会增加更多的结构、过程、体系。人们会把时间都用来开会、写报告,写了又改、改了又写。根据我们的分析数据显示,这些机构的团队会把40%到80%的时间用来浪费时间,他们越做越辛苦,越做越耗时,而增值活动却越来越少。这才是泯灭生产力的罪魁祸首,这才是让人们工作痛苦的原因。 我们的组织在浪费人类智慧。它们和人类的努力背道而驰。当人们不合作的时候,不要怪他们的思想、他们的心理、他们的性格。请看一下他们的工作环境吧。合作与否真的事关他们的个人利益吗?如果他们合作了,他们的个人表现会不会被削弱? 既然如此他们为什么还会合作呢?当我们责怪的是一个人的性格,而不是责怪清晰度、问责制和度量方法时,我们在无效之上又加上了不公正。 我们要创造的组织,应该让人们觉得合作有益于个人。把界线划分、中间部门等这些复杂的协调结构取消掉。不要强求清晰度,选择模糊。模糊没有明确分界线。取消大部分的评估表现的量化指标。速度指的是“什么”,可我们要看的是合作,即“如何”。你如何传递交接棒? 你直接抛吗,还是有效地传递过去?我是不是把我的能量都集中在了可量化的方面:我的腿,我的速度,还是放在了如何传递交接棒上? 你们,作为领导和管理者,是否让人们觉得合作有益于个人?我们组织、公司、社团的未来取决于你们对这些问题的答案。 Yves这个演讲谈到组织的简化,减少中间部门、协调者,这和LeSS的想法不谋而合。软件产品开发过程中,因为人员的增多,我们往往增加更多的角色,设置更复杂的流程,设置更多的职能部门,结果不增加价值的工作也增多了,合作也减少了。与其他大规模敏捷开发框架不同的是,LeSS选择descale,简化过程,减少不必要的协调角色和中间部门,提供相应机制,创造有利于合作的环境促成团队内及团队间的协作,比如特性团队,多团队的联合会议,对一个产品使用唯一的产品待办事项列表等。如果对LeSS感兴趣,可以参加上海8月由LeSS创始人Bas Vodde亲自授课的Certified LeSS Practitioner课程 https://yihuode.io/activities/656...
阅读更多
持续集成和 Git

持续集成和 Git

TL;DR 持续集成就是“持续地集成”,用好 Git 会让你把“持续地集成” 做的更加有效。 引子 这些年,随着持续交付和DevOps的不断升温,似乎让大家忘记了持续集成(以下简称 CI)这个基础实践。更不科学的是,很多团队以为做了持续交付和 DevOps(其实也没做好)就不需要 CI 了。鉴于此,我才有了写本文的想法。 如果你看到这里,还是不理解为什么 CI 会和 Git 有关,那么我强烈建议你看下去,因为你对 CI 的认知中很可能少了核心的东西。如果你明白 CI 和 Git 的关系,你可以跳过下一节,直接从 Git 对 CI 的帮助那节看起。 持续集成到底是什么鬼?为啥和Git有关系? CI 就是“持续地集成”,就是频繁的提交代码并与主干上的代码合并。CI 的出发点很简单,当团队工作在同一个代码仓库(以下简称 repo)时,如果每个人都等到最后时刻提交合并代码,会带来很多冲突,导致开发延期等诸多风险。要解决这个问题,团队中的每个人应该更早更加频繁地提交合并代码,这样冲突就会减少,风险也会更早地被发现。除了频繁提交之外,整个团队工作在单一主干上,以及频繁的运行各种自动化测试也很重要。不过,本文关注在频繁提交这一点上面,其他的就先不展开讨论了。 从 CI 的定义来看,是否有一个 Jenkins 服务器(或者其他类似工具),其实并不重要。Jenkins 只是一个“持续集成系统”而已,没它照样可以 CI,有它团队也不见得在“持续地集成”。CI 系统并不是没用,但是在团队真正做到“持续地集成”之前,CI系统的作用非常有限。James Shore 曾经写过文章专门说这个事情,大家可以参考一下 http://www.jamesshore.com/Blog/Continuous-Integration-on-a-Dollar-a-Day.html。 Git 作为一个几乎要一统天下的分布式版本管理系统,对提交合并代码提供了诸多功能支持,使得程序员可以“随心所欲”地 CI。当然,Git 并非是唯一的也不一定是最早的有这些功能的分布式版本管理系统,如果你用的是 mercurial 或 Bazaar,应该也会有这些功能。 Git 对持续集成的帮助有哪些? Commit 和 Push 使何时将代码提交入主干变得更加灵活可控 频繁提交代码意味着,每次有可工作的代码变更就应该提交到主干,比如小到修改一个资源文件中的文本。在 Git 中提交代码到主干,我们需要 git add; git commit; git push(不考虑命令简写的情况),实际上这要比 svn 这样的非分布式版本管理系统来的复杂(svn add; svn commit)。然而,毕竟不是每次提交都是像修改资源文件那样简单,Git 的分布式设计使得提交代码变得更加灵活可控。 比如复杂一点的场景是,你实现了一个功能的部分需求,剩下的需求仍未实现。这时候,通过提交来保存一个阶段性成果是非常合理的做法,但你可能不希望完成一半的功能进入主干,那么 Git 就帮上忙了。你可以 commit 这部分代码变更但是不 push,然后等剩余的需求实现之后再 commit 并把两个提交一起 push 上主干。如果是 svn,就做不到了。 Commit --amend 让一次提交可包含的代码变得更加灵活可控 换一个场景,你实现了一个功能,代码和单元测试都写好了,但有些代码需要重构。你刚想要开始重构,无奈马上要去开个一小时的会。这时,作为一个专业的程序员,你肯定不希望把没重构的代码 push 到主干,但你可能又担心回来之后重构时可能犯晕。如果用 Git,这时你可以果断 commit 但不 push,之后如果重构犯晕了,就 git checkout 或 reset;如果不犯晕,就 git commit —amend 把重构之后的代码合并到上一个提交,然后再 push。 Stash 让被打断的工作轻松暂存和恢复 程序员常被一些意外的事情打断,比如代码写到一半,被告知(或者自己意识到)需要先完成另一个更高优先级的代码提交。这时,不论代码写到什么程度,都可以用 git add; git stash 把这些代码暂存。等到那个代码提交完成了,再用 git stash pop 恢复之前的代码就好了。 Git 让合并代码变得更加简单和便捷 合并代码时出现冲突可以说是程序员最不愿意见到的几件事情之一。CI 的频繁提交代码使得每次提交的代码数变少了,这样代码冲突的次数会明显下降。另一方面,Git 的实现机制使得代码更加容易被无冲突的合并。即使是出现冲突,Git 提供的合并选项也很丰富,使得合并操作变得非常便捷。 Git rebase (或 git pull —rebase)可以在 push 之前把本地的多个提交重新排列,使得 push 之后 repo 里面的提交成直线排列且更加清晰。如果只有一个团队或几个人工作在同一个 repo 上,rebase 算是一个推荐的做法(当然已经 push 的提交建议不要再 rebase)。不过,如果多个团队工作在一个 repo 上,通常建议 Merge over rebase,因为 merge 会保留提交的顺序,更有利于 bug 的追踪(git bisect)。 如果是两个 repo(注意不是两个 branch,CI 鼓励单分支),其中一个是从另一个 fork 出来的(如新项目fork老项目的代码来修改)。那么,Git cherry-pick 可以非常方便的将新项目的提交合并回老项目中。 开源项目中 Git 的玩法会有所不同 上面介绍的 Git 用法,是针对工作在同一个产品或项目上的一个或多个团队的建议。然而,开源项目中 Git 的玩法可能是不同的。比如,给开源项目发 pull request 的时候,通常要求你先把所有的提交 squash 成一个提交记录,以避免太多提交记录污染主干。我除了搞过一个 react-native 的 npm package 之外,并没有其他开源项目的经验,所以之前的建议不适用开源项目的可能性很大。 Jenkins 对于持续集成有啥用? 我本不想在这里提 Jenkins 了,不过看了 NBA 勇士和骑士第一回合常规时间最后4秒 JR 史密斯的一波“神操作”之后,我决定还是说两句来应个景。和 JR 一样,程序员也会出现这种“神操作”,比如提交代码之前“鬼使神差”地忘记了运行测试。这时候 Jenkins...
阅读更多
保留TL还是引入PO和SM?

保留TL还是引入PO和SM?

TL = Team Leader/组长/队长 PO = Product Owner/产品负责人 SM = ScrumMaster 真正的Scrum要求做根本的组织重新设计。我见过两种常见的试点Scrum的场合:1)项目组和2)组件团队。因为这些结构是现成的,所以使用起来很方便。然而,没有组织重新设计,你没法实施真正的Scrum。 在这篇文章里,我们聚焦组件团队的场合,讨论在准备好进行组织重新设计以实施真正的Scrum之前我们能采用的两种方式。 这是我们的起点。 让我来澄清这里用到的几个术语: 特性:针对产品的需求;它们以客户为中心,具有业务价值 组件需求:针对组件的需求;从产品的角度来看它们其实是任务 任务:组件内部的任务 传统上,TL对组件团队负责,他们对交付组件工作承担问责。 引入团队PO做假的Scrum 这是在组件团队导入Scrum时通常发生的情况。 当然我们需要引入SM和PO的角色,对吗?因为之前是有一个TL,我看到过有两种常见的安排: TL做团队的PO,注意这其实是一个假的PO,因为他明显不对最大化产品价值负责;找另一个人做SM TL做SM;找另一个人做团队PO 无论哪种安排,问责通常还是在TL上。 Scrum角色到位后,团队PO会为组件创建假的产品待办列表,它是组件团队所有工作的唯一来源;SM辅导团队自组织完成组件工作。 这些是好的进展。然而,却还是缺失了真正的Scrum背后最重要的一点,也就是通过对产品和特性进行检查并适应以最大化价值。因此,我们仍然只是引入团队PO做假的Scrum。 保留TL做真的“Scrum” 我想推荐的是另一种方式,保留TL但转变这个角色:1)针对组件做假的Scrum;2)转移焦点到产品和特性;3)推动组织重新设计。 让我来展开: 1)针对组件做假的Scrum 整合所有的组件工作并进行优先级排序(也就是假PO做的事) 辅导团队自组织交付组件(也就是SM做的事) 2)转移焦点到产品和特性 连接组件工作和产品特性 连接组件团队和真正的PO 辅导团队和其它组件团队一起自组织交付特性 辅导真正的PO对产品进行检查并适应 3)推动组织重新设计 传播通过组织重新设计形成特性团队的知识和经验 建立交叉学习和技术卓越以为未来的变革做准备 这种方式更好地遵循了Scrum背后的核心想法,尽管缺失了Scrum角色。因此,我们是保留TL做真的“Scrum”。 只有组织重新设计形成了特性团队后,团队才会直接跟真正的PO工作,并承担端到端交付特性的职责。最终TL会被SM替代,而SM是一个不对交付负责的纯粹教练角色。那样才是做真正的Scrum。 尾注 事实上,《Leading Self-Directed Work Teams》书中定义的TL角色就应该做这些,书中把TL描述成边界的管理者。请不要在组件团队引入团队PO,因为有TL就够了。 英文版:https://blog.odd-e.com/yilv/2018/06/team-leader-vs-product-owner-and-scrummaster-for-component-team.html...
阅读更多
安息吧,集成测试

安息吧,集成测试

TL;DR 绝大部分集成测试都可以被“实现合理”的端到端验收测试所代替。集成测试这个概念应该从测试金字塔中去掉。 引子 最近看到好几篇文章提到集成测试(以下简称 IT)在开发中的作用,常说单元测试(以下简称 UT)和验收测试(以下简称 AT)不够用,所以应该上集成测试,等等。这与我最近这一年多的开发经历非常不一致,我不写 IT,只写 AT 和 UT(我是 XP 和 GOOS 的铁粉)。在 TDD 讨论群里,就集成测试和相关话题也和很多朋友聊了不少,感觉是时候写篇文章了。 到底什么是集成测试? 首先让我们看看到底什么是集成测试。其实这个问题很难回答,我从来没见一个合理和明确的定义。鉴于此,这里就用我自己的定义了。简单来说,集成测试就是一种自动化测试,目的是用来“集成”我们的代码,以确保几个代码模块放在一起是可以工作的。 上图是一个简单的网页表单+数据库的应用架构示意图,以 Java / Spring 框架来实现。那么,IT 可能覆盖的代码用虚线椭圆框表示,而 AT 会覆盖所有的代码,UT 则只针对某一个类或者模块。由图可见,集成测试由于缺乏共识,不同团队的实践也不一样,比如有些会把数据库包含在内,另一些则只是包含框架,Controller 和 Domain Object。另一种情况是,团队并不明确区分 UT 和 IT,而是用“Mini Integration Test” 来代替两者。这种情况与单元测试有关,本文就不讨论了。 什么是验收测试以及“端到端”? 验收测试的定义很明确,不论是 XP 中还是实例化需求中,都会把 AT 当做一个有业务价值的场景来看。而且 AT 可以把这样的场景“运行”起来,以此来验证业务价值没有被破坏。根据定义,通常实现 AT 的时候是“端到端”的。以我之前的经验,要把 AT 做好,关键是要理解“端到端”应该从团队视角出发,而不是用户视角出发。 如上图,用户在 App 上注册这个功能如果从用户视角来看,那么端到端就是从注册开始,直到他收到欢迎邮件为止。但如果从团队视角来看,端到端则变成从注册开始到 Api 后端服务将发送欢迎邮件的请求发送给 CRM 系统为止。如果是用户视角的 AT,最终的验证点是用户是否收到邮件(技术上是可行的),而团队视角的 AT,则只要验证是否正确发送请求就可以了。当然现实往往是残酷的,不少公司 App 和 Api 就是分为两个团队开发,那么 App 团队的 AT 就是到发送请求给 Api 为止,Api 团队的 AT 则是从接收到 Api 请求开始。 我的建议是以团队视角实现 AT,在测试中对所有外部依赖进行隔离(如 CRM 系统,就可以用 mock server 来验证请求并给出假的响应数据 )。实话说,绝大部分应用都有不可控的外部依赖(可能来自组织内部或外部),以用户视角来实现 AT 在实际工作中将变得不切实际,难以落地。 集成测试和验收测试的特点比较 有了定义之后,就可以比较一下 IT 和 AT 了,请看下表: 集成测试 验收测试 目的 集成代码并确保代码放在一起是可以工作的 代表有业务价值的场景并确保其不被破坏 实现复杂度 IT 通常需要启动框架或容器,涉及数据库或 Api 调用时,要进行必要的数据控制和 Mock 后端服务的 IT 不会打开 App 或者浏览器这样的 GUI。而前端代码的 IT  则不会启动所需的服务 AT 需要启动整个被测系统,对所有涉及的数据和 Api 进行控制 AT 会打开 App 或者浏览器来进行测试,测试运行会“途径” 代码中的每一层 运行时间 IT 运行的时间介于 UT 和 AT之间,一个 IT 大概是几百毫秒到一两秒 AT 运行的时间比 IT 长,一个 AT 大概是几秒到几十秒。 如果 IT 和 AT 都做同样的数据控制并 Mock 外部依赖,那么两者的时间差主要是启动 App 或者浏览器所需要的时间 运行环境的复杂度 IT 的运行环境通常是模拟环境,可能不用启动整个被测系统。比如,基于 Spring 框架的 IT 就可以利用 SpringJUnitRunner 来实现 AT 的运行环境是和开发环境一致的,仅仅是环境配置不同(比如测试数据库的链接) 定位问题的难度 如果 IT 失败,定位问题其实并不容易,因为涉及代码也不少 如果 AT 失败,定位问题更难,因为涉及了整个系统 为什么说应该用验收测试来代替集成测试? 基于上面的比较,来看看为什么验收测试可以代替集成测试吧: 目的:IT 的目的是集成代码,代表业务场景的 AT 一样可以集成代码,而且集成的代码更加完整并有业务上的意义。这回合,AT 完胜 IT。 实现复杂度:在 IT 出现的年代,端到端测试框架和服务Mock技术尚不成熟,实现 IT 的复杂度的确比 AT 要低不少。然而,现在这些框架和工具都已经很成熟了,如 cucumber ruby 的生态圈(包括 cucumber/capybara/selenium/appium/mock-server/factory-bot/activerecord 等等),AT 的实现复杂度已经大大下降了。这回合,AT 胜在生态圈已经追平甚至超过 IT 了。 运行时间:这恐怕是 IT 的拥护者们最有信心的一点了,IT 就是比 AT 快,还快不少呢。的确,即使以目前的技术,AT 的运行时间依然是 IT 的10...
阅读更多
项目管理不适合软件开发

项目管理不适合软件开发

首先我想澄清的是:项目管理本身没什么问题,但是把项目管理用在产品管理上这就是问题了,可惜90%的软件开发都是软件产品开发。在我接触到的公司或案例中,项目管理在软件产品开发中带来的伤害要远多于好处。 项目管理 维基百科上项目管理以及项目的定义: Project management is the practice of initiating, planning, executing, controlling, and closing the work of a team to achieve specific goals and meet specific success criteria at the specified time. A project is a temporary endeavor designed to produce a unique product, service or result with a defined beginning and end (usually time-constrained, and often constrained by funding or staffing) undertaken to meet unique goals and objectives, typically to bring about beneficial change or added value. https://en.wikipedia.org/wiki/Project_management 这里面有几个关键:明确的开始,明确的结束,明确的目标,临时的。据我所知,这些在大多数的软件产品开发中都很少见。多大概率你在工作中碰到的需求、产品、功能说在一个时间点结束就真的在这个时间点结束了?总会有各种形式的修改,修Bug,增加,删减等。软件开发中也几乎没有什么临时的,很多时候我们碰到一些“临时”的功能或任务实际存在的时间可都不短,有的甚至比我在公司待的时间都长。 项目管理的思维包含着可预测性。大家可能都知道项目管理的铁三角:范围、时间、成本。 需求的范围,各种时间节点,需要的成本(主要是人力成本),这些是评估一个项目管理是否成功的重要因素。一个项目在预期的时间内按照一定的成本完成了全部的功能,从项目管理的角度来看确实很棒。但是这个项目就真的成功了吗?某大型企业有过一次回顾讨论,他们有个项目按时按量交付了,还没有bug!但是大家都不觉得这个项目成功了,为什么?没有人买也没有人用,当然没bug了。 项目管理的思维方式可能会带来的问题: 长时间的计划 项目管理需要控制成本,因此需要一开始分析或“翻译”需求,明确范围,估算工作,制定预算,我见过不少项目在计划上的时间都多于开发交付的时间。 大量并行项目 计划的时间长,往往意味着同时进行的项目多。我还见过有的公司里一个需求就是一个项目,同时有几十个项目并行很常见。大量并行的项目会使这些项目的计划,追踪等更加的复杂。你可以想想许多公司根据项目抽调人员,还有很多角色是共享的,比如UI/UX,测试,运维等等,再加上项目和项目之间还会有些依赖,要做所谓的“排期”就已经十分的头大了,再稍微有些延期或其它变化就一团乱了。 争夺人员与资源 前面也说道按项目抽调人员是比较常见的现象,因为每个项目为了每个项目的成功都会尽可能的争夺对该项目最有帮助的人员或资源。因此产生的斗争和内耗也会很多,这是典型的局部优化。往往公司里能力越强的人同时做的项目越多,这个人会自己决定手头上事情的优先级。而且也会导致这类人的工作效率的下降,因为需要频繁的切换工作上下文。 关注在需求范围而非目的 项目结束时,大家更关注需求是否做完,也就导致项目过程中关注于计划的执行情况,这些需求本身有没有完成。大家会更少关注于这些需求背后的目的是否达成,是否有在产生价值。我们需要更多的关注产生的影响(Outcome),而不是我们的工作产出本身(Output)。这就要我们不断的验证假设,收集反馈,调整方向。 实现不必要的功能 项目就像一个容器,我们会对里面的“所有东西”进行计划,分析,设计,实现,测试,发布。但是从产品或业务的角度来看,这些都是成本,但是不是都产生价值呢?而且这些不必要功能的存在也会带来维护成本。我们是不是应该对项目的需求范围进行质疑,而不是一味的遵循呢? 降低质量 项目管理更加看重时间和成本,所以当截止日期逼近的时候,大多数开发人员会迫于可种压力在时间和质量之间作出选择,这是质量往往是被妥协的。有时他们选择不重构,不做单元测试,甚至不自测,甚至使用各种秘密武器:复制黏贴,从网上抄一段代码等等。技术负债就这样积累起来了,代码库变的难以维护,后续功能调整越来越难,成本越来越高。对于测试也是一样,测试的压力更大,测试强度也会减弱许多,比如不做回归测试或更小范围的回归测试,测试路径覆盖更少等。很多时候这种质量问题的结果并不会立刻显现。 产品负责人与项目负责人 这里产品负责人并不仅仅指Scrum中的Product Owner,项目负责人有可能是Project Manager或Program Manager。通常这两种角色有着天然的冲突,产品负责人关注价值,项目负责人关注计划的执行。项目负责人占上峰时,产品负责人失去对产品的控制力,只是负责管理需求列表;产品负责人占优势时,项目负责人只有职责却缺少实际控制力。我见过有的公司产品负责人还同时管项目,通常产品负责人大多数时间变成各种事情的协调员,甚至前后端的技术协调。 所以,你得弄清楚你真的是做临时项目吗?如果不是,那么你应该用产品思维来管理。产品通常是长期存在,关注于为客户带来价值,你会持续的对其进行修改、改进、扩展。当然你需要持续的迭代,尽快的从客户或最终用户那里收集反馈来调整后续的工作。即使你是做软件外包项目,如果你和客户是长期合作关系,依然你可以用产品的方式来做,因为你的开发过程会更加的顺畅,而客户可以获得更多的价值。 PS,有些公司搞所谓的“敏捷转型”也立个项,用项目管理的方式来做。我也是不赞同的,因为这样很容易变成只是在有限的时间内把一些实践给搬到组织内,未必产生实质性的效果,也不利于持续学习与持续改善。我们应该像开发产品一样,不断的试验调整来进行持续的改善我们的研发过程。...
阅读更多
你用错 Page Object 了吗?

你用错 Page Object 了吗?

什么是 Page Object ? Page Object 是在基于UI的自动化测试中经常被用到的一种设计模式。其目的是对在测试代码中被反复使用的页面元素和操作进行封装,从而去除重复代码,使其更容易被理解和维护。如果需要了解更多有关 Page Object 的内容,可以参考 https://martinfowler.com/bliki/PageObject.html。 Page Object 是如何被用错的?  虽然 Page Object 被广泛使用,但是经常能见到这个模式被用错。让我们先看看下面的 gist,这是一个误用的例子。 public class AddBudgetPage {    @Autowired    UiDriver driver;    public void open() {        driver.navigateTo("/budgets/add");    }    public void inputMonth(String month) {        driver.inputTextByName(month, "month");    }    public void inputAmount(int amount) {        driver.inputTextByName(String.valueOf(amount), "amount");    }    public void save() {        driver.clickByText("Save");    } } public class BudgetSteps {    @Autowired    AddBudgetPage addBudgetPage;    @When("^add a budget with month \"([^\"]*)\" and amount (\\d+)$")    public void add_a_budget_with_month_and_amount(String month, int amount) throws Throwable {        addBudgetPage.open();        addBudgetPage.inputMonth(month);        addBudgetPage.inputAmount(amount);        addBudgetPage.save();    } } 先来解释一下这个代码。AddBudgetPage 是一个 Page Object,他提供了四个方法(open, inputMonth, inputAmount, save)来操作添加预算的页面。而这些方法则被 BudgetSteps 中的 add_a_budget_with_month_and_amount 方法来使用,以此来实现 UI 自动化测试中添加预算这个动作。BudgetSteps 是 Cucumber JVM 中定义的 Step 文件,关于 Cucumber JVM 可以参考 https://github.com/cucumber/cucumber-jvm,这里就不深入了。AddBudgetPage 中的那个 driver,则是对 Selenium web driver 的一个封装,与本文所提及的内容无关。 那么,这个 AddBudgetPage 到底哪里错了?其实就是那四个方法有问题。这些方法实际上是“添加预算”这个业务动作的“分解操作”,是实现细节。从封装的角度来看,以 inputMonth 为例,inputMonth 只是封装了输入预算所在月份的操作细节,即表单中月份输入框的 name 是 month 这个细节。这种粒度的封装可以避免将来输入框 name 修改带来的麻烦,但如果添加预算的业务变了,比如增加了一个叫“部门”的新属性,那么就不得不为 AddBudgetPage 增加一个新方法 inputDepartment。同时,所有用到 AddBudgetPage 的 Step...
阅读更多
认识组织选项背后的系统动态:一份还是多份产品待办列表

认识组织选项背后的系统动态:一份还是多份产品待办列表

在多团队的产品组织中,存在一个选择:采用一份还是多份产品待办列表。因为试点起始于一个团队或者产品本身起始于一个团队,通常会从一份产品待办列表出发。引入多个团队后,有些组织选择采用多份产品待办列表,而另一些组织则选择保留一份产品待办列表。当采用多份产品待办列表时,通常会由不同的PO对每份待办列表负责。 以下CLD(Causal-Loop Diagram:因果回路图)显示了这个话题背后的系统动态。 一份产品待办列表的驱动力 因为只有一个产品,所以很自然会想采用一份产品待办列表。R1回路可以这样读: 采用越少份产品待办列表 透明性越好 产品整体性越好 采用越少份产品待办列表 这是个潜在的良性循环,最终导致采用一份产品待办列表。 为什么采用多份产品待办列表? 那么,为什么还有组织选择采用多份产品待办列表呢?有三个主要的平衡回路在起作用,分别是B1回路、B3回路和B5回路。与R1回路一起,它们构成了“成长上限”的系统基模。 B1回路可以这样读: 采用越少份产品待办列表 技能差距越大 开发效率越低 团队越焦虑 采用越多份产品待办列表 B1回路显示了来自于团队专业化的限制。为了充分利用团队的专业化以获得效率,产品待办列表本质上变成了团队待办列表以匹配他们的技能。这个动态与采用通用团队还是专业团队背后的动态是类似的。其实另有根本解决方案,我们会随后展开。 B3回路可以这样读: 采用越少份产品待办列表 每份待办列表中的故事越多 PO澄清需求的工作量越大(假设PO来澄清需求) PO越焦虑 采用越多份产品待办列表 B3回路显示了来自于需求澄清的限制。一个常见的误解是PO要为团队澄清好需求。如果需求澄清都由PO来做,这就成了采用一份产品待办列表的限制因素。其实也另有根本解决方案,我们会随后展开。 B5回路可以这样读: 采用越少份产品待办列表 团队间耦合度越高 产品探索和决策的效率越低 PO越焦虑 采用越多份产品待办列表 B5回路显示了来自于探索和决策的限制。这里的假设是每个团队有自己的PO,所以当每个PO可以独立决策时效率就更高。其实也另有根本解决方案,我们会随后展开。 这些是限制我们采用一份产品待办列表的主要力量。它们限制了R1回路从而伤害到产品整体性。其杠杆点在于找到根本解决方案以弱化这些限制力。 寻找根本解决方案 针对B1回路、B3回路和B5回路,B2回路、B4回路和B6回路分别提供了相应的根本解决方案。然而这些方案因为有延迟所以是长期的。短期解决方案(也就是采用多份产品待办列表)转移了我们对长期解决方案的焦点。这本质上就是“舍本逐末”系统基模所描述的现象。 1. 团队专业化  B2回路显示了围绕团队专业化问题的根本解决方案,可以这样读: 开发效率越低 团队越焦虑 学习越多 团队技能越广(一段时间后) 技能差距越小 开发效率越高 我们可以不通过采用多份产品待办列表来减少技能差距以获得开发效率,而是聚焦于学习和扩展团队技能广度,最终获得更高的开发效率。 R2回路是“舍本逐末”中的上瘾回路,可以这样读: 采用越多份产品待办列表 团队感知到越少学习的需要 学习越少 团队技能越窄(一段时间后) 技能差距越大 开发效率越低 团队越焦虑 采用越多份产品待办列表 当采用多份产品待办列表多少解决了开发效率问题时,我们会倾向于更少关注学习和扩展团队技能广度,从而变得更依赖于多份产品待办列表。 2. 需求澄清  B4回路显示了围绕需求澄清问题的根本解决方案,可以这样读: PO澄清需求的工作量越大 PO越焦虑 团队参与需求澄清越多 PO澄清需求的工作量越少(一段时间后) 我们可以不通过采用多份产品待办列表来减少PO工作量,而是聚焦于让团队参与到需求澄清,最终带来PO工作量的减少。延迟是因为团队需要学习如何与用户有效交互以及相关领域才能把需求澄清工作做好,这需要时间。 R3回路是“舍本逐末”中的上瘾回路,可以这样读: 采用越多份产品待办列表 每份待办列表中的故事越少 PO感知到越少需要帮助 团队参与需求澄清越少 PO澄清需求的工作量越多(一段时间后) PO越焦虑 采用越多份产品待办列表 当采用多份产品待办列表多少解决了PO工作量问题时,我们会倾向于更少关注如何让团队参与需求澄清,从而变得更依赖于多份产品待办列表。 3. 探索和决策  B6回路显示了围绕探索和决策问题的根本解决方案,可以这样读: 产品探索和决策效率越低 PO越焦虑 团队间对齐越多 产品探索和决策效率越高(一段时间后) 我们可以不通过采用多份产品待办列表来减少团队耦合以获得探索效率,而是聚焦于让团队间对齐并增加共同决策的能力,最终获得由一组团队和PO共同协作产生的更高探索效率。延迟是因为创建团队间对齐和形成共同协作能力需要时间。 R4回路是“舍本逐末”中的上瘾回路,可以这样读: 采用越多份产品待办列表 团队间耦合度越低 感知到越少需要跨团队对齐 团队间对齐越少 产品探索和决策效率越低(一段时间后) PO越焦虑 采用越多份产品待办列表 当采用多份产品待办列表多少解决了探索效率问题时,我们会倾向于更少关注创建对齐和形成共同协作能力,从而变得更依赖于多份产品待办列表。 总结 当我们做一个产品时,最好的情况应该是采用一份产品待办列表。我们分析了是什么阻碍我们这样做,那些因素是我们需要去移除的。常见的有三个方面的原因让我们选择采用多份产品待办列表:团队专业化、需求澄清、产品探索和决策。我们寻找了对应的根本解决方案,并看到采用多份产品待办列表可能产生的“舍本逐末”陷阱。...
阅读更多
认识组织选项背后的系统动态:一个还是多个产品负责人

认识组织选项背后的系统动态:一个还是多个产品负责人

我原先以为这个选择本质上和一份还是多份产品待办列表是相同的。当我细想后,发现还是值得把它写成单独的话题。作为两个最流行的大规模敏捷框架 - SAFe和LeSS - 在这上面就做了不同的选择。SAFe中的ART(敏捷发布火车)和LeSS中的LeSS(到8个团队)规模上是近似的。在ART中,定义了产品经理和若干团队PO(产品负责人);而在LeSS中,却只定义了一个PO跟所有团队工作。在本文中,我们会探索围绕一个还是多个PO这个选择的系统动态。 在SAFe里对ART的描述中,它提到了定义团队PO的原因。 “规模大了,一个人就没法既处理产品和市场策略又专注于敏捷团队。因此,产品经理和团队PO们会一起驾驶火车。” 让我们来探索为什么这么选择以及它产生的后果。 优先级排序 胜于 需求澄清 以下因果回路图呈现了引入多个PO来分担需求澄清工作量所产生的相关动态。 引入多个PO作为减轻一个PO所需承担需求澄清工作量的解决方案反映为B1回路,它可以这样读: 一个PO澄清需求的工作量变高 引入更多PO 一个PO澄清需求的工作量变低 在这个解决方案背后有一个常见的误解,以为PO唯一负责澄清需求。在单团队Scrum里,这更像是一种选择,Scrum指南里这样描述: “PO可以做以上工作,也可以让开发团队做。” 以上工作包括需求澄清。 而在多团队Scrum里,如果我们希望让一个PO能够和多个团队工作,团队分担需求澄清工作就变得很必要了。LeSS里这样阐述: “一个LeSS里的PO专注于努力思考优先级,但和团队协作澄清需求。并且他会鼓励和帮助团队直接和真正的用户/客户对话。他作为一个连接者,而非中间人。” 这个替代的解决方案反映为B2回路,它可以这样读: 一个PO澄清需求的工作量变高 团队参与需求澄清越多 团队和客户工作的能力越强/团队具有更丰富的业务领域知识 一个PO澄清需求的工作量变低 R回路解释了为什么多个PO的做法如此常见,它可以这样读: 一个PO澄清需求的工作量变高 引入更多PO 对PO澄清需求的依赖越大 团队参与需求澄清越少 团队和客户工作的能力越弱/团队具有更贫乏的业务领域知识 一个PO澄清需求的工作量变高 引入更多PO 如果读了这个系列之前的文章,你一定已经认出了这里的“舍本逐末”系统基模。 合同游戏的现状 以下因果回路图呈现了从研发引入多个PO来应对业务方的改变阻力所产生的相关动态。 业务和研发之间传统的工作方式是基于合同游戏的。业务和研发协商一个发布的合同,然后业务就交由研发交付合同。在导入敏捷之前双方是没有基于迭代的协作的。当你想有更多PO时,对业务方就意味着更多的改变。阻力应运而生,最终导致在研发这边创建了更多PO。这样做消除了阻力同时又满足了对PO角色的需要。现状得以保留。 B1回路是个速效方案,它可以这样读: 业务方需要的改变越大(需要更多PO) 产生的改变阻力越大 在研发这边引入更多PO 业务方需要的改变越小 B2回路是个根本方案,它可以这样读: 业务方需要的改变越大(需要更多PO) 产生的改变阻力越大 对业务方的辅导越多 团队和业务之间的协作越多(或者作为PO,或者作为干系人,关键是基于迭代来协作) 带来越多价值和越大灵活性 业务方需要的改变越小 R回路解释了为什么这么容易就回复到现状,它可以这样读: 业务方需要的改变越大(需要更多PO) 产生的改变阻力越大 在研发这边引入更多PO 团队和业务之间的协作越少(因为团队和PO之间的协作变成了研发内部的协作) 带来越少价值和越小灵活性 业务方需要的改变越大 是的,你又一次看到了“舍本逐末”系统基模。 结论 我看到过两种常见的一个产品多个PO的情况。 在许多互联网公司,这些团队PO就是低级别的产品经理。他们更多工作在战术层面,而非战略层面。当他们喂给团队详细的规范和用户界面草图时,团队在产品探索上的参与度就会很低。这不仅丧失了让团队贡献于产品探索的机会,也为达成产品交付所需的共同理解制造了障碍。 在更传统的行业,从研发这边引入团队PO的做法很常见。当他们关注于需求澄清时,他们本质上退化为传统的业务分析师。有很多理由反对业务分析师的角色,我最喜欢的是Martin Fowler和Dan North在2007伦敦QCon上做的主题演讲中阐述的,简而言之就是,“桥比渡轮更好”。 当你选择有多个PO时注意后果! 英文版:https://blog.odd-e.com/yilv/2017/03/seeing-the-system-dynamic-1-vs-n-product-owners.html...
阅读更多
认识组织选项背后的系统动态:狭窄还是宽泛的产品定义,第二部分

认识组织选项背后的系统动态:狭窄还是宽泛的产品定义,第二部分

在第一部分,我们分析了把平台定义为产品的情况。现在,我们来分析把产品领域定义为产品的情况。那些产品确实都有客户视角,但是我们有可能定义一个更宽泛的产品,然后那些产品就变成了宽泛产品定义下的产品领域。让我们进一步分成两种情况,一种是把解决方案定义为产品;另一种是把产品系列定义为产品。 把解决方案定义为产品 解决方案包括若干产品,它们之间交互产生客户价值。让我们来看两个例子。在电信网络中,无线接入网是一个解决方案,而基站和基站控制器是其中独立的产品,也就是网络解决方案中的网元。在电子商务中,电子商务平台给客户提供了端到端的解决方案,而购物、支付、物流是其中独立的产品,也就是整体解决方案中的元素。解决方案往往会演进成一个开发的生态系统。我们可以把解决方案重新定义为产品,那样在同一解决方案中的产品就变成了产品领域。 1. 产品化、同步和灵活性 虽然在解决方案中产品之间的关系与第一部分中阐述的应用产品和平台产品之间的关系有所不同,以下呈现的动态却很相似。 产品化是推动狭窄产品定义的一个关键驱动力,这由B1回路呈现。产品化的支持包括市场、销售、预算等。一旦这方面有差距,我们把原本只是属于同一产品的不同领域定义为独立的产品。这增加了产品导向,带来更好的产品化支持,最终关闭这方面的差距。 为了在解决方案层面交付价值,相关的部分必须同步起来。独立产品降低了相互之间的同步程度,从而延长了周期时间。更长的周期时间带来时间上的压力,它形成了对产品独立和狭窄产品定义的制约。这个动态由B2回路呈现。 产品独立也会在狭窄产品之间产生部门墙效应,这降低了整体的灵活性。当一个产品有更多高价值的工作时,是很难从另外产品调动团队工作到这个产品上的。当整个解决方案还是充满不确定性,并且整个组织的规模还较小时,我们会期望有更高的灵活性。因此,它也形成了对产品独立和狭窄产品定义的制约。这个动态由B3回路呈现。 与把平台产品化类似,在解决方案中形成独立的产品也最好通过涌现而非事先计划。过早的产品独立带来的问题比它解决的问题还更多些。 2. 局部创新和整体创新 局部创新和整体创新是另一对权衡。局部创新指的是在每一个狭窄产品内的创新,而整体创新指的是在解决方案层面的创新。 狭窄产品定义通过聚焦帮助推动局部创新,这由B4回路呈现。它是推动狭窄产品定义的驱动力。然而,产品独立产生部门墙效应,从而损害了同一解决方案中的产品间协作,降低了整体创新。当感知到整体创新不足时,我们可以通过定义宽泛的产品来降低部门墙效应,增进协作,从而提升整体创新。这个动态由B5回路呈现,它形成了对狭窄产品定义的制约。 也有组织选择不同的平衡回路来应对整体创新的不足。他们不是通过宽泛产品定义,而是通过创建跨产品的工作组来提升协作,以推动整体创新。这个动态由B6回路呈现。理论上来说这是个好主意,然而实践中把那些工作组的结果落实到各自独立的产品中是一个挑战。定义宽泛产品和创建工作组也是可以互补的。 把产品系列定义为产品 产品系列包括若干服务于同一市场但不同客户群的产品,比如一些是高端的,另一些是低端的。通常它们也会共享大部分的代码库。我们可以把产品系列重新定义为产品,那样在同一产品系列里的产品就变成了产品领域。 1. 关注、竞争和混乱 我们首先来分析与业务和客户相关的动态。对客户的关注能增加客户满意度,而让客户感到混乱则降低客户满意度。这里的竞争是指同个产品系列里的不同产品对业务和客户的竞争。 狭窄产品定义的一个驱动力是更好地服务客户。产品定义得越狭窄,那些对应的客户得到关注越多。这增加了客户满意度,从而客户压力得到释放。这个动态由B7回路呈现。 当同一产品系列里的每个产品都各自发展时,相互的对齐变弱。产品之间的竞争加剧,最终意识到对齐不足。这会触发重新定义一个宽泛的产品,从而增加对齐以使竞争可控。这个动态由B8回路呈现,它形成了对狭窄产品定义的制约。 有意思的是当对齐变弱时,客户感到的混乱也会加剧,因为他们可能使用同一产品系列里的多个产品,会收到不同的甚至是冲突的市场信息。这种混乱感使客户满意度降低。这个意外的后果由R1回路呈现。B7回路和R1回路一起构成了“饮鸩止渴”系统基模的动态。 2. 重复工作和通用组件 让我们再来分析与开发相关的动态。重复工作对开发成本有负面的影响,而通用组件则能降低成本。 当同一产品系列里的每个产品都各自发展时,它们之间的透明性变低,从而产生更少的通用组件,导致更多重复工作。重复工作增加了开发成本,因此成本压力变大。针对重复工作的一个解决方案是把产品系列定义为宽泛产品,而之前的产品就成了这个产品里的产品领域。这样做增加了透明性,以使更多的通用组件涌现成为可能,带来重复工作减少,进而开发成本降低,成本压力得以释放。这个动态由B9回路呈现,它形成了对狭窄产品定义的制约。 针对重复工作还有另一个常见的解决方案,就是围绕潜在的通用组件创建组织。这些组织驱动组件被使用,以使它们成为真正的通用组件,带来重复工作减少,进而开发成本降低,成本压力得以释放。这个动态由B10回路呈现。你可能已经注意到这本质上就是我们在第一部分阐述过的“平台是一个组件”的情况。 B9回路和B10回路是创建通用组件的两种不同方式,一种是通过透明性使它成为可能,另一种是定义它。在我的经验里,涌现通常比事先定义工作得更好。 总结 狭窄还是宽泛的产品定义是个很大的话题,有着非常多的上下文差异。这两篇文章(第一部分和第二部分)还远非全面。我总结一下其中涉及的主要权衡和陷阱。 产品化是狭窄产品定义的一个关键驱动力。因为正确的狭窄产品通常是涌现的,我们应当避免过早将它们分离出来。 周期时间和灵活性的考虑是对狭窄产品定义的主要制约。无论定义的是真正的产品还是只是平台组件,都是如此。 通用组件和重用平台对降低开发成本有利,但并不需要把它们定义为产品并附于开发组织。 狭窄产品定义可能在以牺牲整体创新为代价推动局部创新。 英文版:https://blog.odd-e.com/yilv/2018/03/seeing-the-system-dynamic-narrow-vs-broad-product-definition---part-2.html...
阅读更多
认识组织选项背后的系统动态:狭窄还是宽泛的产品定义,第一部分

认识组织选项背后的系统动态:狭窄还是宽泛的产品定义,第一部分

什么是产品?这是一个组织设计中的关键问题。你可以狭窄或者宽泛地定义产品,由此定义产品的范围是一个连续体。我们将分两部分来认识不同选择背后的因素和动态。在第一部分,我们会分析将平台定义为产品的情况;在第二部分,我们会分析将产品领域定义为产品的情况。 平台是个在很多产品组织里都很流行的概念。平台经常被当作产品来对待,对应到组织,围绕它有相应的产品待办列表和团队。在多数情况下,平台不面对外部客户,因此本质上还是组件。平台和应用一起形成一个产品,这种情况呈现在上图的左半部分。在有些情况下,平台有独立于应用的外部客户,因此确实是产品。平台和应用就是两个面向不同客户的产品,这种情况呈现在上图的右半部分。让我们分别来展开。 平台是一个组件 为什么组织选择把平台定义为产品,即使它本质上只是一个组件?为了重用 - 多个应用可以重用同一个平台,从而节省开发成本。B1平衡回路呈现了该动态。目标是达到成本预算;行动是定义狭窄的产品,也就是平台,来推广重用。背后的推理是平台提升了重用程度,因此降低了开发成本,从而减轻成本压力。 为什么组织不选择把平台定义为产品?这里有另一个平衡回路B2在起作用。当定义了更小的平台后,客户价值的交付会牵扯更多的平台。彼此的同步程度越来越低,因此周期时间越来越长。这带来了时间压力,形成了对把更多平台定义为产品的抑制力。归根结底这是个在某个时期哪个平衡回路占据主导的问题。 让这变得更为有趣的是,异步性带来了等待,由此产生浪费,反而增加了开发成本。这样就形成了一个增强回路R1。B1回路和R1回路一起构成了“饮鸩止渴”系统基模的动态。当B1回路主导时,R1回路处在恶性循环中,从而伤害了达到成本预算的目标。当B2回路主导时,R1回路处在良性循环中,不仅对时间目标有利,还能帮助达到成本预算。这部分的动态体现在下图中。 回到重用的初衷,有什么其它办法能增加重用程度?内部开源是一种方式。采用它最大的挑战来自于其自然发展的本质 - 只能培育它而不能控制它。 平台是一个产品 当平台除了内部应用之外也面向外部客户时,它确实是一个产品,这时就涉及不同的权衡了。 在这种情况下,把平台定义为产品主要的驱动力就不在于开发成本了,而是需要将产品带入市场所需要的聚焦和支持。B3回路呈现了这一点。产品化的支持包括市场、销售、预算等。一旦这方面有差距,我们把平台定义为与应用产品独立的产品。这增加了产品导向,带来更好的产品化支持,最终关闭这方面的差距。 但是,这同时会对应用产品带来影响。当平台自主运作后,来自应用的需求就更难同步响应了。因此周期时间变长,导致时间压力变大。这就是之前的B2回路,它对把更多平台定义为产品形成了一种抑制力。 在现实中,平台产品更多是涌现出来,而不是被正确地预先定义出来。我见过很多平台从未变成真正的产品;那些成为真正产品的平台却很少是被预先定义的。和重用组件一样,平台产品的涌现最好也是被培育而非计划。当过早把平台定义为产品时,它损害了应用产品的交付,同时也没能在做出成功的平台产品方面达到预期效果。 在第二部分,我们会来看是将其定义为一个狭窄的产品还是将其定义为一个更宽泛产品中的产品领域。 英文版:https://blog.odd-e.com/yilv/2018/03/seeing-the-system-dynamic-narrow-vs-broad-product-definition---part-1.html...
阅读更多