在当今数字化浪潮中,软件开发不仅是技术领域的核心驱动力,更是企业创新与商业成功的战略支点。特别是软件定义汽车的时代,软件研发的规范化管理成为车企的难言之痛:软件版本如此多,如何测试?全量测试还是采样测试?软件版本发布如何管控?软件质量如何保障?软件功能为什么总是赶不上造车的节奏?软件是如何集成的?敏捷会让车企的软件开发一夜之间发生神奇的变化?….
本篇文章依据《软件研发全攻略》这份详实的教程资料,为您揭开软件开发的神秘面纱,以科普的方式探讨其理论基础、关键模型、实战技巧以及组织与人才发展等重要议题,旨在为读者提供一幅全景式的软件研发导图。
一、软件开发基石:软件开发生命周期模型的选择
软件开发生命周期模型是组织软件研发活动的框架,它定义了开发过程中的阶段、顺序、迭代方式以及各阶段间的关联 (见图1)。
图1
软件开发生命周期模型,大家耳熟能详的是经典的瀑布模型和敏捷开发模型。
瀑布模型:
瀑布模型遵循严格的线性顺序,从需求分析到详细设计,再到编码、测试和维护,每个阶段必须在前一阶段完全完成后才能开始。瀑布模型适用于需求稳定、技术路径清晰的项目,但其僵化性可能导致应对变化的能力较弱,一旦前期需求定义有误,后续阶段修正的成本极高。
关于瀑布模型,我们需要知道,目前看到的瀑布模型(见图2)更多是停留在了理论模型基础之上。实际上,在1980s, Fred Brooks, 著名的产品开发畅销书《人月神话》作者,图灵奖获得者,在NASA内部会议上指出,“在超过370亿美金的投资项目中,只有2%的项目使用了纯粹的瀑布模型,75%的项目或夭折或没有使用.”
图2
在现实的世界里,更多的是采用了基于瀑布模型演化的进化模型,如螺旋模型,V模型等。他们都融合了瀑布模型的结构化特点与迭代思想。螺旋模型特别适用于高风险项目,通过反复的风险评估和原型迭代降低不确定性;而V模型(见图3)强调开发与测试的对应关系,确保每个阶段的验证与确认工作紧密相连。V模型成为了产品工程,特别是软硬一体的嵌入式产品开发的核心骨架,也是产品开发使用最为广泛的模型。像汽车行业的ASPICE标准,功能安全的ISO26262标准,信息安全的ISO21434标准,基本都是根据V模型制定了相应的规范要求。
图3
敏捷模型:
敏捷开发模型则以快速响应变化为宗旨,倡导迭代开发和持续集成。它强调团队协作、用户参与以及适应需求的灵活性,通过短周期的迭代(如Scrum中的Sprint)快速产出可用软件,并根据反馈进行调整。敏捷模型更多地关注了软件开发过程中的工程实践,对于软件交付后的运营提及不多。交付后的管理更多的还是采用传统的软件生命周期管理的模式。
敏捷软件开发模型同样存在多种实操模型,例如XP,FDD,等。目前应用最广的还是团队级敏捷SCRUM模型(见图4)
图4
敏捷开发在实际落地过程中有两种具体的项目管理方式:基于时间盒的迭代计划(见图5)和基于流的迭代计划(见图6)。采用不同的迭代计划,将决定了敏捷项目每个冲刺(SPRINT)的交付内容。我们需要注意的是,因为产品形态及产品技术架构的复杂度不同,组织架构的不同,如果迭代规划方式选择与之不匹配,敏捷反而会引入更多的混乱和内卷。
例如,如果产品是单一架构的(monolithic Architecture)且功能依赖多,如果采用时间盒的迭代规划方式,会出现待开发的新功能不得不削足适履,进行功能分拆用户故事,确保能在一个时间盒的窗口交付,反而导致大量的模块之间的相互依赖,交易成本(Transaction Cost)巨升,协调工作冗长,从系统论的维度看下来,反而是降低了效率。针对这种情况,要么是改变时间盒的跨度,要么是采用基于流的迭代工作模式。
图5 (来源:From Prince2 Agile)
图6(来源:From Prince2 Agile)
软件开发的模型选择:
“There’s no singular technique or process that will bring about significant improvements in software development productivity”
– No Silver Bullet—Essence and Accidents of Software Engineering
Gerald Weinberg, Fred Brooks, and Grady Booch
面临乱花渐欲迷人眼以及病急乱投医的汽车软件开发,到底如何选择自己的软件开发模式呢?正如Fred Brooks所言,没有单一技术或模型能够显著提成软件开发效率。我们需要的是因地制宜,选择适合自己组织和产品属性的研发活动的模型。
在实际工作中,我们应该且必须学以致用,灵活适配合适的软件开发模型,而不是简单地照猫画虎,仿照各种敏捷框架,站会,结对编程,…(题外话:其实,适配性(Adapability)才是业务敏捷的精髓所在)。不管选择何种开发模型,其核心目的是更快、更好地交付客户价值和业务价值。具体来讲,可以基于Stacey矩阵,选择合适的开发模型(图7)。当然,除了Stacey矩阵提供的需求确定性和技术确定性的两个维度外,还需要考虑团队的成熟度,团队成员的技能经验,工作地点分布,团队规模以及组织文化等因素。
图7
二、需求分析与架构设计的艺术
软件开发始于需求的获取与需求开发的过程(通常将这个过程称为需求工程阶段)。需求的获取主要是从市场需求,用户需求,业务等维度,理解并分析企业所在的行业,国家,地区,适用的法律法规等各个维度,定义软件产品的需求。
近几年来,随着国内互联网造车的兴起,互联网用户需求分析的工具也逐步引入到垂直行业,也成为国内传统造车企业纷纷攘攘去学习的重心。但从第一性原理来看,需求获取的原理没有改变,变化的是传统企业缺少需求获取的数字化手段,缺少人物画像的细节管控。
需求获取的方法手段很多,我们总结如图8所示。
图8
在对软件产品功能进行定义的过程中,往往采用的是多种方法的综合应用,确保功能能够满足最大数量的用户期望。同时,我们要关注,对于TOC业务与ToB业务的需求获取方法,也存在着差异。无论是从调研对象,调研数量以及调研方法,在实际过程中,要注重理论与实践的结合。
这里,特别给大家推荐一个用来识别或改进产品可用性功能需求(Usability)的强大工具–用户历程地图(题外话:对于其他如非功能性需求的定义与改进,建议采用其他工具方法)。图9展示了对电车用户充电活动的用户历程地图,通过一张纸,可以清晰地将产品功能的优劣以及待创新的功能点描述清楚。
图9
需求获取只是开启了整个软件开发的序幕。我们下一步要做的是需求的确认。需求的确认,是确保软件产品的开发“做正确的事”。需求确认的方法包括了VOC,焦糖布丁法,Y分析法,数据分析法等等。
为什么要进行需求的确认呢?其实,这涉及到了人类认知的过程,如图10所示,当我们看到现实的人形机器人图片时,我们会根据自己的认知(Perception)和我们个人的知识(Knowledge)对其进行描述。然后,我们将我们自己脑海里,经过自己认知过滤过的图片,用自己的知识,包括文字语言对其进行描述,这个过程,将不可避免的引入人为的错误。所以,在专业的产品研发环境中,我们意识到这个人类认知的过程偏差,所以需要建立规范的工具方法,如需求文档的评审,需求撰写的规范,等,作为“获取正确需求”的底线保障,确保最大可能地不失真。而敏捷思想里强调的“客户合作胜于客户合同”,也正是基于这个不可更改的事实做出的更合理的过程建议。
图10
需求的开发包括需求分析与需求的分解与分配的过程。它是软件产品开发“正确做事”的过程。这个过程可以使用类似FAST功能分析图,EFFBD图,UML建模或者其他建模工具实现。也可以使用其它不同的工具方法,如KJ法,KANO法,QFD法,Pugh 矩阵法等等,帮助我们有效工作。
需求开发从产品定义语境出发,逐步细化分解功能,最后分配到子系统和模块。这个过程是用户可见的功能和可感知的非功能性期望,转化为我们软件产品能力的过程。如果是0到1的产品开发,这个过程与产品架构设计交互迭代,最终形成产品的雏形;如果是基于原有产品架构的功能增加,则更多的工作是基于原有架构进行需求分配的过程。当然,不排除原有系统需要重构,才能满足客户的功能要求的情况。
而架构设计则是将技术需求转化为系统的蓝图,涉及功能模型定义、架构评估方法选择、物理架构布局等多个环节。软件产品常见的技术架构包括了C/S架构,MVC架构,分层的SOA架构等。但具体的架构设计,要考虑的不仅关乎技术实现,更是一种权衡艺术(Trade -Off),需要在功能、成本、时间、用户期望等多种因素间寻求最佳平衡。如图11,当面对客户“过河”的需求,架构设计可能需要考虑桥梁、船只、潜水艇,飞机等多种解决方案,每种方案背后代表了不同的技术复杂度、投资规模与时间周期,系统架构就是需要在不同的解决方案中选择最合适的,而不仅仅是技术最优的。
图11
在架构设计过程中,可以运用启发式问题法、KJ法、QFD等工具进行评估与决策,有助于识别最合适的架构。同时,评估软件架构的有效性,还可以通过创建原型、迭代开发、模型模拟等方式获取直观反馈,必要时引入量化指标进行深度分析。
康威定律揭示了一个重要规律:软件架构往往反映出组织内部的结构。这意味着,良好的组织设计有助于催生高效、协调的软件架构,反之亦然。因此,在软件开发过程中,应充分考虑组织架构对技术实现的影响,确保架构设计既能满足功能需求,又能顺应组织协作模式。
<未完待续>
原文始发于微信公众号(ARVO INSIGHT 价值洞察):软件研发全攻略(一)