一、为什么需要敏捷开发
1、什么是软件的生产制造过程
什么是软件的生产制作过程?软件的需求收集、设计、编码、测试、打包、部署是软件的制造过程吗?可能很多人听到这些名词的时候会说:“对,这当然就是软件的生产制造过程,这就是我们明天在做的事情”。好吧,那我们就一块来看一下,这是不是软件的生产制造过程。我们来拿一个汽车的生产制造过程做为比较。如果你要造一辆汽车,我们需要有一辆原型车。制造原型车的过程我们把他叫做设计过程。当我们有了原型车后,我们会把汽车原型车相关的图纸、所有的装配方案、所有的零件的组装方式全部都交给生产线的工人。生产线的工人会按照既定的流程以及方法去不停重复的生产制造同样的汽车。也就是说一辆汽车下了生产线后,两辆同样型号的汽车肯定是完全一致的。作为一个消费者,你在4s店买的汽车肯定不希望和别人买的同样型号的汽车是不一样的。我们也不会允许我们的工人在生产线上琢磨我的这个零件到底应该咋样安装。到底应该装到这里或者什么地方。包括甚至一个螺丝应该拧几圈这在汽车生产线上都有非常明确的预订方案。我们在讨论生产过程的时候,我们实际上是在讨论不停重复制造同样产品的过程。用同样的思路,我们来思考下制作软件的生产制造过程是咋样的。刚才提到的需求、设计、开发、测试、构建、交付其实是在制造软件的原型车。因为经过这个制造过程出来的每一个软件都是不一样的。那到底什么时候软件才不发生变化,才和我们上面所说的汽车制造过程 同样呢?其实就是你打好了一个包,右键不停的复制&粘贴。只有在这个过程中,才是软件的生产制造过程。因为在这个过程中,你所复制的这份软件才不发生任何变化,而我们日常所管理的软件开发的整个流程其实都是在重新的设计软件。软件每产生一个版本和上一个版本肯定是不一样的。所以这是软件开发的本质。但是我们在咋样管理软件开发过程?传统的软件项目的管理思路比如瀑布式的思路,它其实是借鉴了在生产厂家里不停重复的生产制造过程的方法,试图把他用于软件开发的重复设计的过程。自然他是行不通的。所以敏捷开发才是软件开发的正确姿势。都不用讨论敏捷开发和瀑布流开发那个好那个坏。如果到了今天还在讨论这个问题,大家应该有一个正确的认知就是只有敏捷开发方式才是处理软件开发正确的方式。因为瀑布式开发其实是在用一个错误的方法来管理一个错误的过程。我们用传统管理方式管理软件,就好像你开着车一口气要开到这条路的顶端。那你准备咋样开过去呢?传统的项目管理方式就是启动车挂上档,松开方向盘,踩下油门闭上眼睛,然后希望我们能够安全迅速的到达彼岸。但是事实情况是路上可能会有各种惊喜。但是你在开到哪里之前根本就不知道。而实际上我们在传统的项目管理方式去管理软件开发过程的时候,其实就是既定好一个计划,我们认为按照这个计划可以到达目标,不希望中间产生任何的变化。希望最终能够把这件事情做好。那么自然是做不好的。
2、敏捷让我们重新定义管理
敏捷到底带来了什么?其实敏捷重新定义了我们应该到底管理一些什么。我们在传统的项目管理里面,我们管理的内容就是成本、时间和范围。我们认为只有这三个因素在一个项目里面才是可变的。那么在传统项目管理里面,那些东西是不可变的呢?它认为价值和质量是不可变得。这是什么概念呢?就好像盖好了一栋大楼。这个大楼已经盖好了50多层了。外装修已经做完,开始做内装修了。这时候大楼业主来了。你作为这个大楼基建工程的项目负责人。业主说:“这个大楼该的不错,能不能给我加个地下室?”我相信你但是的心里想法一定是非常崩溃的。但你可以想一下,我们平时在做敏捷开发的过程中,你是不是每天都遇到这样的疯子。如果你一名开发人员,你明天遇到的最让你奔溃的人就是产品经理,朝令夕改。但是其实产品经理也很冤,产品经理听到的客户的心声其实也是朝令夕改。永远都是他看到一个东西时候说:“哎,这不是我要的!你为什么不能改一下呢?”他所要的这个修改,其实就已经是在加地下室了。但是对于用户来说,他根本意识不到这一点。我们专业人员讨论的软件分层对于普通用户来说,他完全是不可理解的。对他来说,这就是一堆代码。既然是代码为什么不能改呢?而实际上你这堆代码是压在所有代码下面的。但是压在所有代码下面这一点对普通用户是不可理解的。我们接着在说大楼的问题。客户想给大楼增加一个地下室,其实是在改变大楼的价值。同时也改变了大楼的质量。但是这两件事情在传统的项目管理里面肯定是预先设置好的。因为任何人都明白,当一个楼盖好后是不可能在加一个地下室的。或者说成本是非常非常高的。但是这件事情摆在软件里面,许多客户就认为是可以做的,没有那么高成本。他认识不到成本的问题,所以他就会相对比较随意的修改我们最终交付的价值和质量。当然这件事情我们也不能完全责怪我们的用户,因为用户没有见过他所要的东西。这就是前面所说的,我们的软件一直在做设计而不是说在做生产。用户在拿到我们产品之前他根本就不知道也不可能预先体验到这个产品最终拿到时候是什么效果。所以他也无从帮你去定义他所要的价值和质量是什么。这就决定了在软件开发的时候我们的价值和质量包括成本、时间、范围都是可变因素。而敏捷就是让我们认可这件事情是正常的。敏捷首先认可说,在一个软件产品生命周期里价值、质量以及时间、范围和成本都是可变的。在这个前提之下,我们在来讨论关键管理的过程。从过程角度讲,到底传统的开发模式和敏捷开发模式在处理高度可变的对象的时候,他采取的措施有什么不同呢?我们在比较传统开发和敏捷开发的时候,到底在比较什么?其实我们比较的是瀑布式和迭代式两种过程模式。什么是瀑布式?就是我们按照一个顺序的结构去处理一个软件的整个生命周期。去先处理计划、分析、设计、编程、测试和最后交付。我们认为整个过程执行一遍以后,这个项目结束了,软件的开发过程结束了。实际上,任何一个软件当时交付给用户的时候,它还远远没有到达结束,其实才刚刚开始。迭代式说白了其实就是小瀑布。可能有很多来自敏捷社区的人不认可这一说法。但实际上他就是把一个串行的过程把它缩短到一个比较短的时间范围内。等结束后还是要重复执行这个串行的过程。任何时候要开发出一个产品或者一个软件的功能它都必须要经历分析、设计、编码、测试的过程。少任何一个过程,这个东西做不出来的。所以当缩小到一定范围后,软件开发永远是瀑布的。但是问题在于,当我们跳出这个比较小的范畴站到一个相对比较高的位置去看软件开发过程的时候其实他永远是迭代的。如果我们看整个软件的生命周期,它永远需要发布版本,每一个版本和前面的版本都是不一样的。既然他的整个生命周期是这样,他为什么在软件开发过程中不使用一种和他匹配的管理过程来管理呢?所以就出现了迭代式的开发过程。迭代式开发过程的好处就是首次发布的时间大大提前了。而我们真正在软件里面投入类似编码这样真金白银的过程其实是变得更加短了。这样我们就有更多的机会,让用户告诉我们所做的软件是不是对的。然后再根据用户个我们的反馈去决定我们在下一个迭代里面到底该做些什么。所以我们永远不要去假设我们的需求是对的。我们需求永远需要给到用户由用户去确认这个需求是对的。而用户确认的不是需求,而是需求转换成功能后用户的体验。从这个角度来说,软件里面所有的需求都通通不是需求而是假设。这个需求直到做出来之前它都不是百分之百正确的。没有人说他是百分之百正确的。就算是最终用户他也没有办法确认这件事情。因为他没有见过。所以在敏捷开发里边我们的计划到底是什么?敏捷开发里面到底应该咋样管理这样一个过程。大家永远要记住一句话。在敏捷开发里我们的计划不是用来限制变化的。而是用来适应变化的。计划本身也是一个被管理的单元。通过缩小计划单元的大小,来提高计划对于变化的适应程度。软件研发是一个复杂过程,在软件开发过程中,如果你要把软件管理好,你需要把复杂的过程简单化,然后试图去管理简单过程。而不要试图用复杂方法处理复杂过程。
二、软件研发过程中到底管理了什么
软件开发有很多的模型,不论你采取的是敏捷开发模式还是瀑布式开发模式永远需要做需求、需要做设计、需要做编码、需要去管理任务、需要去写代码,需要把代码编译成包。在把包部署到环境里这个是不变的。需要我们变得是我们在看待这个过程的时候,他们之间的关系是咋样的。我们应该咋样去处理不同模块之间的关系。最典型的例子就是,项目初始的时候都会有产品和需求。需求是用户所需要的某一个特定的场景。他希望咋样去用这个软件。而产品是说这个产品中到底有哪些东西。我有哪些菜单,哪些模块、哪些服务。他是纯粹技术的角度。所以架构模型是从技术角度来描述的产品。而条目话需求是从用户的角度来描述我们的需求。而设计过程所做的就是将用户要的条目化的需求和我们的架构模型产生联系。然后分析清楚这些需求到底会咋样影响当前的架构。我们常说架构在演进。为什么架构在演进?因为有需求在不停的冲击他。当有需求冲击他的时候,就需要不停的适应它,来改变我们的架构。从这个角度讲,如果我们的需求不停的进来,我们也就没有办法找到一个永远稳定的架构去满足所有的需求。这是不可能做到的,既然有影响,就会发生改变。既然发生改变就不再是原来的东西了。所以不要追求设计出一个完美的架构去支持你的软件跑上十几二十年。所以我们永远要理解我们的架构是跟着需求一起变的。当述求变了后,我们的架构也跟着变化。这个是架构模型和条目话需求这样的一个关系。项目是从条目化需求过来的。其实你思考下,在你自己的软件开发的过程中是这样的吗?可能大家觉得可能不是这样的。一般来说我们在收集到需求进行需求分析以后会产生一份软件功能说明书的东西。这个东西原始的用户需求已经被分解重新组合成了产品中某些模块的功能需求,我们在组织开发计划的时候一般来说大家会从功能性需求开始来列任务。而这里不是这样做的,这里是直接从原始的条目化需求直接组织项目计划。而把架构模型放在旁边作为参考。这就是敏捷开发的思路在同样的模型上产生的影响。敏捷开发思路希望我们的开发团队一直维持一个条目化需求的视角。通过这个视角保证我们后期交付的内容永远是用户所需要的。这样的话,就能够保证我们在开发过程中开发团队看到的东西和我们用户所要的东西是高度一致的。不然的话就会出现到最后我们这个任务做完了但是发现没有办法交付。因为他忘记了当时用户要的高度是什么。这种事情在大型项目中经常会出现。就是我们所提到的版本对齐的问题。什么是软件开发中的版本管理?版本管理其实是在衔接软件开发过程中的管理属性和功能属性中两个最主要的过程。我们希望做什么叫规划的版本管理,它需要和我们要交付的版本管理产生关联。那么这个关联、关系就是所谓的版本管理。一个版本管理做的好的团队,他能告诉团队里面的任何一个人你现在在做什么。任何人在回答你在做什么的时候,他脑海里包含的是那些需求、那些代码、那些测试、那些环境部署,每一个人的脑海里产生的影响都是一致的。那么这种团队,他的版本管理做的好。做的不好的团队我们的测试可能有一套自己的版本管理的方法。我们开发有一套关于版本管理的说法。我们的架构师有一套版本管理说法。我们的需求人员有一套版本管理说法。而我们的运维团队又有另外一套版本管理说法。那么在这种情况下,就说明他的版本管理做的不好。所以版本管理其实并没有那么复杂。就是要在所有的不同角色之间让每一个人使用同样的语言,产生一个共同的,对于我们当下正在做什么、要做什么、应该做什么这件事情一个普遍的唯一的统一的认知。那软件研发的过程是这样的,我们应该管理什么呢?我们应该管理各个节点和节点对应的关系,也就是点和线。咋样的关系最合理,我应该把他变成咋样的关系。这个其实就是我们需要考虑的过程。把我们写项目拆解成开发任务和测试用例,通过开发任务进行编码,一系列的代码变更进入到一个版本包。这个版本包在通过某一种特定的流程进入到不同的环节。这个就是大家日常制定的开发流程。我们在devops中经常要讨论的一个概念是我们从端到端的角度整体的度量它,让它提高效率。但你脑子里如果没有一张整体的视图,你是做不到这一点的。所以管理属性和工程属性是软件开发汇总非常重要的量大领域。要把它们衔接起来,就是要把版本管理做好。版本管理是做什么的呢?就是让研发中的任何人都可以用一种简单的语言描述来回答我们在做什么、做了多少、还有多少要做。
三、敏捷和DevOps的关系
大家应该都熟悉一家公司叫携程。它是中国互联网中一个非常早的先行者。它出现后把可以在大街上可以看到的机票代理行业已完全消灭掉了。携程发展到一定程度后,航空公司发现出了一些问题。航空公司不知道用户在做什么,大家都通过携程去买机票,而不通过航空公司自己的渠道了。航空公司丧失了一定的和客户的议价权。感觉就像航空公司给携程打工似的。用户都在携程手里而不在航空公司手里。但是航空公司想想。它了花那么多钱建了好多机场。培养了好多飞行员,还买了飞机。我的投入比你携程的投入要大的多吧。拼什么我要受你的制约呢。所以从大概2016年底到2017年各大航空公司都开始去推自己的自营渠道。为什么他这么做,因为他意识到了如果它不这样做,他们所有的销售渠道都会被携程控制。这样他们就丧失了对市场的议价权。所以他意识到这个情况后,开始去返工互联网。传统行业在反攻互联网。这里我们要思考一个问题,为什么一开始是携程出来而不是航空公司自己在网上卖机票?类似的情况还有很多。这里就不一一列举了。当用户的入口被某一个特定的渠道绑定后,其实这个渠道有非常多的想象空间。这就是我们说得,用户的了解可以帮助服务的提供者创造更多的价值。为什么我们要提这一点呢?我们现在讨论的是DevOps和敏捷到底什么关系。还是前面讨论的一个问题,为什么不是一开始就是航空公司在网上卖机票而是携程?相信当时航空公司也看到了互联网带来的机会,但是没有办法那么快的把这个想法落地。变成一个真真实实的产品来给到用户。所以在众多的行业中,到底什么样的行业需要敏捷和DevOps。其实反而还是一些传统的行业,最典型的是金融行业他们是非常需要敏捷和DevOps的。在这个行业的人,他是非常非常依赖IT的。但是他同时有觉得自己不是做IT的。这个感觉就是他其实意识到了一些可以去探索的场景。但是因为自身肌体的能力反应没有那么快,所以没有办法那么快的捕捉到这样的机会。所以敏捷是一种做事的思路。就是我们前面说的,我们在讨论软件开发过程的时候,我们要把价值和质量的变化考虑到我们的范畴之内。我们所要面对的是一个高度变化的情况。我们需要有新的想法来适应这种变化。但是有了新的想法后,咋样把新的想法落地这个考的其实就是DevOps。所以用一句话来总结敏捷和DevOps的关系就是敏捷提供创新的大脑,而DevOps提供的是创新的肌肉。
四、研发效能提升的两大法宝
到最后我想在给大家提示下我之前提到过的粒度的问题。当然还有另外一个问题,就是解耦的问题。这两个关键词是希望大家能够记住的。这里把它称为研发效能提升的2大法宝。其实大家不用太多的关注敏捷、精益、持续交付、devops等这些外表很热的词。其实他们做的事就是一个,就是要提高我们的研发效能。什么是效能?所谓效能就是持续适应市场变化,调整自身价值输出方式和速度的能力。如何能够做到这一点,其实就是两件事情。第一个粒度,第二个耦合。先说粒度,刚才我们在讨论敏捷的时候粒度的话题说得已经比较充分了。当一件事情是高度变化的情况下,我们想要用一个既定计划去适应它是很困难的。基本上是做不到的。当这个复杂程度到了一定程度以后它的复杂程度就超出了你的适应能力了。咋样能提高管理手段和管理过程的适应能力呢?其实就是要减小我们的管理单元。管理单元是什么,就是我们在软件开发过程中需要被管理的内容。可能是团队也可能是需求。可能是任务、测试、交付或者我们每一次写的代码提交。这些内容如果说比较小的话,你会发现至少有一点是可以保证的。既然这东西比较小,也就是说你犯错误的机会就比较少。也就意味着我们适应能力会变强。所以缩小粒度就是我们从管理的角度提升研发效能最重要的一个思路。另外一个工程解耦做软件开发的人应该都知道,我们希望在研发过程中能够让我们的速度快起来。就希望大家不要受到很多因素的制约。我可以自己独立的部署自己的模块,可以独立的测试我自己的子系统。不要把整个系统拉起来才要进行开发和测试。其实这些思路都是进行解耦。我们在开发过程中所涉及到的代码、模块、交付、流水线、环境等这些东西他们的耦合度越低越好。这样才能保证我们能够更快的、更小的范围之内更灵活的去交付我们想要交付的东西。这样我们整个适应能力就会提升。