为什么“燃油方案”改了三次版?聊聊我对建模的一些理解
前言
前段时间重温了一波UML,除了复习了一波基础的语法和使用场景之外,还有一个很重要的目的就是:学习如何建模。
关于建模,我之前看完了《大象:Thinking in UML》的前两章后,写了一篇阅读笔记《一个掉头发的问题:什么是建模?》,当时写完了之后感觉对建模的概念稍微有些掌握,但是过了一段时间之后又开始有点生疏、模糊了。
于是最近我又重温了这篇文章,同时又再读了两遍《大象:Thinking in UML》的前两章,结合最近项目中遇到的一个小案例,我决定写一篇关于建模实践的心得文章,也就是这一篇。
简单理解建模
关于建模的定义,我直接摘录书上的解释,因为我感觉这个定义挺准确的,也很简洁。
建模(Modeling),是指通过对客观事物建立一种抽象的方法用以表征事物并获得对事物本身的理解,同时把这种理解概念化,将这些逻辑概念组织起来,构成一种对所观察的对象的内部结构和工作原理的便于理解的表达。
上面建模的定义本身就和建模工作一样非常抽象和难以理解。
我大概总结了一下我自己的理解,然后用借用一张图和几段稍微通俗的一些语言来概述它。产品日常工作中需要使用建模,是因为我们需要对一些事物建立一些概念化的描述,然后以此来让其他人理解这些事物。
例如业务提出的需求是做一个“采购系统”,但是“采购系统”这几个字很虚无缥缈,然后具体是怎么样子,有什么功能,要怎么做,需要产品去逐步调研,设计,然后建模,最后将建立好的模型通过一些图形化或者文字化的表达,传达给开发和测试人员等,最后大家认知达成一致之后,上线一款满足业务需求的“采购系统”。
要完成建模,首先是确认抽象角度,这其实就是面向对象的一个分析过程。一个需求的背后有很多人,事,物和规则,单单拿“人”来说,也会有不同的抽象角度,例如常见的就是按职位或者使用功能的角度来抽象,采购管理模块的人分为“采购员”,“业务员”,“供应商”;但是如果按使用系统的角色来抽象,则采购管理模块的人可以分为“采购发申请角色”,“采购处理角色”,“管理员”,“采购审核人员”等。
不同的抽象角度汇聚在一起会构成“问题领域”,问题领域中那些重叠的部分其实就是需要重点关注并解决的问题,因为在不同的抽象角度都能得出此问题,则意味着该问题是高频且核心的。
其次是确认业务用例,当我们在第一步的时候确认了若干个抽象角度之后,由于抽象角度背后是特定的场景,所以我们应该对相应的场景进行梳理。例如我们是按职位或者使用功能的角度来抽象,这个抽象角度背后的场景就有“采购员在什么条件下要做什么事达成什么目标”,“业务员在什么情况下会需要发起采购申请?要如何发起?”,“在采购环节中要如何与供应商关联,关联之后能做什么”……
如果说上述的大白话,还是让你对建模有点琢磨不透,似懂非懂的话,那我拿一个我最近在做的实际案例来进一步解答你的疑惑。
为什么要做燃油方案?
之前有提到过,海外仓尾程物流的费用一般包含两个部分基础运费+附加费
,附加费中有一个比较特殊的“燃油附加费”,它的计算公式是(运费+部分附加费)* 燃油费率
。
燃油费率具有以下几个特点:
和时间有关系,不同的时间段,费率不一样,所以费率的更新比较频繁; 和物流商有关系,不同的物流商,燃油方案(生效时间范围和费率)不一样,但是也有一些物流商的渠道是相同的燃油方案; 费率是一个百分数(小数),需要乘以基础费用才能得出具体的燃油费;
无论是从业务的角度,还是从技术的角度,燃油方案看起来都是一个很简单的需求,容易理解,关键字段也很少,业务关联性也不复杂。
起初的时候我也不以为然,感觉就是一个很简单的需求,差不多想了一下,然后找竞品也看了下,就输出了一个产品设计方案,准备到时候快速评审一下。
但是实际上我前后改了三个版本才解决这个“小需求”,期间还一度让我感觉自己是不是进入了“知识诅咒”,陷入了“死胡同”出不来了。
因为建模失败,改了三个版本
Round1:参考竞品来建模
参考了好几个竞品之后,我发现大家对燃油方案的设计都是最简单的平铺型的设计,也就是把所有创建好的燃油方案按时间排列。
燃油方案也是一个比较抽象的概念,为了让大家更好地理解它,所有我们在对其进行建模的时候,需要先确认一个抽象角度,因为确定了角度就会让我们有一个目标。
“平铺型”就是一个建模的角度,通过这个角度,我们得到了目标:平铺式的展开所有的燃油方案,以便于更简单方便地对燃油方案进行管理。
而管理燃油方案就会涉及到多个场景,这就是建模的第二步———找出特定的场景。我们需要创建燃油方案,编辑燃油方案,删除燃油方案,应用燃油方案等,以上这些是场景中的“事情”,然后借此我们还需要去挖掘这个场景中的“人”和“规则”。
当我们确定了抽象角度,找到了这个角度背后的场景之后,建模也就完成了大半,最后要做的就是对这些场景进行梳理和推敲,是否能够完全满足业务的需求,有没有遗漏的点或者阻塞的点等。这其实也是UML中梳理用例的过程,所以当我们在梳理用例的时候,本质上也是在做建模这件事。
如果一个抽象角度不能完成建模,那就要继续回到第一步,发掘更多的抽象角度,从实际的工作经验来看,简单需求可能一个抽象角度就可以完成建模,但是复杂需求往往需要多个角度,多个场景,多个用例同时构建才能完成建模。
让我们再回到燃油方案建模这件事的起点时刻,首先要做的就是去发掘它的抽象角度,从多个竞品的实现方案上来看,平铺型的视角是用的最多的,所以我们第一版也采用了平铺型的视角去建模,去梳理业务用例,去完成产品设计。
确认了视角之后,接下来就是挖掘场景,从“人”,“事”,“物”,“规则”几个方面去构建场景,然后发现了这种方案有以下几个问题。
方案平铺后数量太多,会不断新增,使用的时候不太方便; 燃油方案需要经常更新,而且有些时候会提前设置,等到时间点后生效,平铺型的燃油方案不利于更新,如果修改已有数据,则破坏了正在生效的计费方案;如果追加新的燃油方案,则必须要求燃油方案重名,用户操作出错的风险太大;
Round2:使用平铺型+状态限制来建模
鉴于平铺型的视角会有一些问题难以解决,我们在短暂的讨论后决定要调整一下方案,换一个视角来发掘业务场景,试图找到更好的解决方案。
在第二版的方案中,我们引入了一个新的“状态”字段。大多数场景还是和第一版一样,只是通过状态来做一些核心业务逻辑的判断。
燃油方案名可以重复,重复意味着使用一个燃油方案后,当后续不断的新增/修改燃油方案后,只要名称是可以匹配的,就可以使用这个燃油方案来计费。
然后通过状态来判断,“生效中”的燃油方案不能重名,只有一个,“未生效”和“已失效”的燃油方案可以重名,可以有多个。状态是通过每天的定时任务来判断的,根据设置的日期和当前日期进行比较,判断应该在什么状态。
这个方案最后还是被我们评审的时候Pass掉了,原因是还是有一些风险点和体验不好点,原因如下:
“未生效”的燃油方案如果重名且生效日期范围有重合,则会导致当自动生效的之后,“生效中”的状态可能会同时有两条;如果限制了不能重合,则又要限制“未生效”和“生效中”的也不能重合,这样感觉和状态又无关了,引入这个概念没多大的意义,因为方案一就是限制了不能重合; 定时任务更新状态可能会失败,需要引入重试机制或者兜底机制;兜底的机制是每次用的时候再去查当前的日期是否满足生效日期范围,如果每次都要查,那么定时任务更新状态也没意义了,直接实时用时间去判断就够了;
Round3:采用树状结构来建模
因为方案一有一些漏洞或者体验不好的点,所以才想到了方案二,引入了一个状态,但是实际在处理这个状态的时候,发现很是鸡肋,有用但是又不完全有用……
看似一个简单的需求,但是设计出来的产品方案总是有明显的漏洞和瑕疵,我感觉可能一开始的思路就错了。
也就是说:竞品们采用的从平铺型视角去建模,有可能本身就是错误的或不好用的。
意识到这一点之后,我完全抛开了竞品的干扰,直接从最本质的需求和业务逻辑触发,重新发掘新的建模视角,最后发现采用树状结构才是更合理的解决方案。
首先,燃油方案名称本来就是一个索引,一个壳子。业务说经常要更新燃油,这里的更新只是对燃油方案中的明细进行更新,常见的就是修改生效日期、失效日期和燃油费率,燃油方案名称一般来说是不会修改的,也不能修改,因为方案是一直被计费规则所使用的。
其次,燃油方案还有一个很关键的场景需要满足,就是对已经发生了的物流费进行重新计算的时候,需要使用物流发生的时候的燃油明细去计费,也就是历史的燃油明细也很重要,需要留底备用。
最后,树状结构可以保持燃油方案的简洁,配置计费规则的时候选择的是燃油方案的主档信息,而在使用/调用燃油方案的时候,再根据日期时间去查询该方案下的燃油明细。当然,对于燃油明细还是要确保生效日期范围不能重复的,这样计费的时候才能找到唯一的一条数据。
总结
最后回过头来看的时候,燃油方案这个需求确实比较简单,我们最终使用的方案也没有特别的创新或者颠覆性的改造,但是整个经历却很跌宕起伏,很让我触动。
一个小小的方案,因为一开始的建模方向搞错了,导致陷入了一种不撞南墙不回头的境地,让我总是在自我怀疑,为啥别人可以这样做,我自己这样做的时候却不行了呢?
通过三次的建模,三种不同的视角带来的差异也让我特别惊讶,很多时候我都以为建模只是在复杂场景下才用的上的比较玄乎的技能,但事实上好像简单场景也能用得上。只是场景过于简单我们大多数时候第一反应切入的视角就已经可以做到最优解了,所以对建模视角的选择这个事情不会有太深刻的记忆。
其次是关于竞品参考这件事也让我有些顿悟,批判性思维在产品领域真是时用时新。大家都在用的方案也不一定是最优解的方案,错误的概念和理解传播的多了,用的人多了,也不能改变它是错误的本质……
这一篇文章写了2个礼拜,断断续续始终没有灵感和动力一口气写完。一方面是工作节奏太紧了,抽不出太多的时间;另一方面是在建模方面,我还是只是一个初学者,边写的时候还在边找资料论证,我发现市面上关于这一块优秀的教材还是太少了。
用这个案例来阐述我对建模的理解,也许没有我想象中那么贴切,或者有一些理解可能还是错误的。如果你在此领域有更好的案例或者学习教程,欢迎与我沟通交流。