作为程序员,刚刚开始学会写代码,常常是接过需求就开始撸代码。有时候发现,写完代码,需求变了。更多时候,觉得写业务代码枯燥无聊,没有技术含量。另外一边的事实却是,项目里面研发人数变多了,项目的质量缺却变低了,多人开发也不过是一个个单打独斗的组合而已。
经历过PC互联网的不断深入发展,移动互联网的蓬勃生长,互联网进入了成熟繁荣期,研发环境也发生了巨大变化;从原来一个人,一把键盘,写完代码就上线,变成了更加规范的研发体系和更多人参与的共同协作。
研发流程不断加速
为了尽可能提高需求交付速度,跟上市场的变化,我们通过不断提搞软件交付的速度,尽可能的,从需求,编码实现,测试,发布的流程中不断优化,利用CICD,加速迭代。
多人协作无处不在
现在的软件开发团队,即使再小,也有2-3人一起研发,更别提测试,运维,运营,产品人员。一方面是软件产品的竞争日趋激烈,需求日益复杂,堆砌人力成了必然;另外一方面是专业性的要求,精密的行业自然要求精细化的职业划分。
研发流程的速度提上去了,团队的人也变多了,但是,需求变更依旧让广大研发同学感到痛苦,项目质量还在日益变差。
需求变更之痛
需求变更的痛苦为难了广大研发同学,前脚刚为了优化性能,采用了kv存储,后脚需求就变成了要支持模糊查询;这是一种典型的架构设计不合理,导致业务需求的实现方式受限。
更令人痛苦的,还有产品需求变动多,今天简单实现下,上线看看效果,明天用户脾气很大提了个诉求,再加一个功能上线,产品功能变成补丁加补丁。一方面是研发同学渴望一个完整又严谨的需求,提完需求进入研发阶段就不许改;另一方面是产品同学受到各方面的压力,只希望先把主要问题解决下,细枝末节以后再说。
项目质量变差
项目代码腐烂的另外一个原因是多人协作,团队的人越多,代码反而变得越烂似乎成为了趋势;为什么多人协作没有提高代码质量呢?一方面,多人协作实际上只是分摊的需求实现而已,大多数需求实现的分配中,反而尽可能将协作变少,避免实现受阻。另外一方面是,不同人的代码模块,设计意图和代码风格也截然不同。维护前人代码,如果没有全局视角,了解设计意图,也只能是往里面加补丁代码了。
项目代码腐烂容易导致程序员出现错觉,一是业务代码没什么料在里面,不如搞基础建设;二是业务需求不可能完整又严谨,最终也会变来变去的,最终质量低下的锅,一大半要给提需求的人。
在写代码之前要进行设计和建模。相比历史短暂的IT行业,很多工业,建筑行业的精密性,都离不开前期的设计,在分析设计之后,按照图纸规划施工,写代码也应当如此。
设计建模的有效性源于,一,重新回到业务的跑道,跟业务一致;二,设计建模才能让协作真实有效;
为什么研发实现需求跟业务一致很重要呢?研发和业务需求的摩擦,本质是研发实现跟实际需求不一致,无论是研发走偏了,没有理解需求,还是需求本身不能满足涉众的利益,都会使得最终上线的功能需要回炉重造,折磨项目组的成员。业务项目,需求很重要,是整个项目质量的源头,源头的问题不处理好,会一直发散扩大,问题传递到尾部,甚至到了产品上线,对整体造成的损耗越大。从设计的语言上看,设计的层次有所不同,不仅仅有代码细节上的设计,也有业务上高层次的设计,高层次的设计是用业务的术语去表达,最贴近业务实际情况,也能帮助研发同学发现业务中不合理的点。
设计和建模分为好几个部分
业务建模
分析涉众利益
分析涉众利益之前,需要找到涉众,一般要经历以下步骤:
表格是一个很好的表达方式,我负责的一个商户从第三方商城采购刷脸设备,由仓配系统配送设备的业务,可以表达如下:
愿景:将设备更多更快且准确无误成本低地卖给商户。
一般而言,涉众的利益是否被满足直接决定了软件产品的成功与否。而分析涉众利益需要进行详细的调研,研发同学可以根据产品的调研看到对应的涉众,及其利益。
业务用例图
知道了涉众的利益之后,就要分析业务流程,并对现有的流程进行改进。软件产品没诞生之前,业务是如何被处理的,找到原来业务的处理方式则可以梳理出业务用例。
笔者负责的一个业务是向购买设备的商户配送设备,对于业务团队的实际业务来说,用户购买设备有业务价值,业务用例如下:
物流公司和设备渠道商都是辅助购买设备的执行者,因此放到右边。值得注意的是,业务用例要体现价值,虽然在实际业务流程中,商户同时做了很多事情,比如签收设备,但签收设备不能反映业务价值,故而只有一个购买设备的用例。
业务流程分析
可以看到,在原来的业务流程中,配送设备的流程是在全部业务流程中较为繁重,人肉工作量大的流程片段,不符合涉众利益;
所以很明显,我们的系统需要改进流程,替代人的部分工作
新的流程有效地满足了涉众“将设备更多更快且准确无误成本低地卖给商户”的利益诉求。
业务序列图中,每一个箭头代表的是职责,在业务序列图中,需要考虑的是职责的层次问题,过于小的职责放入流程图中,会导致信息过载,忽略最有价值的职责。在上图中,运营核对设备的配送信息是一个很重要的职责,在原来的需求中体现比较弱,研发同学可以借助业务流程的分析来分析需求中不合理的地方,完善需求,避免后期的改动,前期越是完善,后期的损失成本越低。
业务流程分析是一件很复杂的事情,研发同学可以利用需求中的信息,同时加上自己跟涉众的日常沟通和调研,把握核心的涉众利益,业务用例和业务流程,就可以解决大部分在需求上的理解偏差问题。
系统建模
系统建模需要做的事情
系统用例图
如下是仓配系统的系统用例图:
系统用例规约
有了业务流程图和系统用例图,需要根据进一步细化系统边界上的约束,保证系统的稳定性。系统执行者与系统的交互细化了详细的约束,系统的稳定性才能提高,如果没有仔细列出约束,有可能会忽略一些边界条件,导致系统的故障;如:仓配系统不考虑来自第三方商城订单要配送的设备数量限制,则会因为第三方商城出现的错误,导致资产损失。
配送设备:
因为步骤2,3,4还有其余可能的路径,称之为扩展路径。
类的分析与设计
这可能是大多数研发同学比较熟悉的领域,经典的设计模式,类之间的关系,泛化,组合等。但是类从哪里来呢?是从需求之中凭空产生?又或者突然灵光一闪,有了类的雏形?对类的进行设计与分析之前,需要做的是找到他
识别类
找实体名词
知道了有这三个类还是不足够我们识别具体的类,识别具体的类需要去业务流程,系统流程,系统规约中经常出现的名词。在上面的流程图中,订单,商城,设备,物流,用户是反复出现的名称,说明这些类必然存在。
找到这些业务实体,就是找到类的第一步。
找到属性
类的属性也不是凭空产生的,需要对业务实现有价值,用户不一定有姓名,在物流上下文中,用户的属性就只有ID,收货地址。找到那些对于系统实现必不可少的属性,放到正确的类中。如仓配系统中的订单,包含订单号,商品,用户。用户则有收件地址。
在仓配系统中,用户只有一个地址,在商城的系统中,用户则有多个地址,充分说明了,不同的上下文中,类的属性不是固定的。
找职责
从业务规则和约束中,可以找到一些实体应当有的职责,如订单,就有验证合法性的职责。
有时候,有些对象看起来信息很富裕,但是却没有什么职责,说明他是一个值对象,像上图中的用户和收件地址,我们不关心他的id,只关心收件地址,收件地址就代表着这个用户。
状态机
找到类和对应的职责,对于一些主要的实体类,还需要设计出他的状态机,清晰的状态机能有效地厘清系统内的一些事件和状态,增强系统整体的健壮性。
仓配中的订单,从用户购买的待发货状态,到通知物流发货,再到实际发货,物流签收有一些列状态的演变。
在多人协作的项目中,不断提高项目质量,除了依靠代码之外的工程手段,还要依靠设计建模。
从具体实践的角度来看,设计建模在不同的环境中,调整具体的流程和侧重具体的节点,也能够实现快速高效,不会导致繁琐和低效能的现象。