战略设计
在经过业务分析后,整个系统的轮廓就被大致勾勒出来了,但这明显是一个极为粗略的轮廓,或者称为骨架。
接下来,就可以按照这个轮廓或者骨架所展示的样子,来对它做更进一步的分析和设计,赋予灵魂,填充血肉,让它符合各方的期望。
和业务分析一样,战略设计的路线图大致是这样子的。

根据
业务分析输出的内容,从限界上下文识别开始,依次推进到上下文关系映射、统一语言和战略层面的技术决策。其中,
限界上下文识别和上下文关系映射可以说是整个DDD中最为重要的部分,这两个地方做出的设计,将直接决定今后系统的整体可用性、可维护性及运行效率,它是关键中的关键。而
战略层面的技术决策主要包含五个部分的内容,这也是决定系统运行效率的重要因素。但其实像技术栈、数据架构、治理架构和微服务的取舍很多公司都有着约定俗成的方案,或者直接采用已有的成熟经验。唯有应用架构这部分,对于不熟悉DDD的团队来说,可能就要好好斟酌一番了。
说明:
PUF/D指的是Python + UWSGI + Flask/Django。
业务分析输出
业务分析中得到各种业务流程、业务用例和业务子域,都可以用到战略设计中。
因为这次准备上线运营的特色农产品认养平台属于团队首次开发,而且该农场之前也没有任何建设电商平台的经历和经验,所以根本没有什么过往的遗留系统可供拆解和借鉴。
至于第三方系统,指的不是开发中所集成的那些功能接口,例如,第三方支付、物流接口、人脸识别、短信验证、地图导航等组件,而是指平台建设方作为甲方所额外采购的软件或者服务。例如,用于仓储管理的WMS系统,或者用于企业资源管理的ERP系统。
这些东西,甲方目前也没有。所以可以说,本次开发的电商平台完全是从零开始。
因此,基于DDD的认养管理核心子域目前也没有任何除电商平台之外的外部系统与它打交道。
限界上下文识别
虽然通过业务分析初步划分出了不同的子域(或业务模块),但如何准确地界定这些子域的边界,尤其是能够进一步细化出每个子域内部所包含的更下一层的子域,就需要通过限界上下文识别来实现了。
这时候一般都会通过事件风暴的方式来寻找限界上下文。
另外,在识别限界上下文的过程中,也会回过头来对之前分析和设计出来的内容(业务蓝图、业务流程、业务用例和子域划分等)不断地进行迭代、细化、调整与完善,补全可能被遗漏的业务功能,澄清可能出现的需求误区。
例如,在经过事件风暴后,就新增加了之前在业务用例中没有考虑到的分单与合单业务用例。
将梳理出的与认养相关的所有的事件(动词行为)按照时间线进行排列后,其内容如下。
事件风暴
认养事件 -> 事件拦截 -> 人工审核 -> 用户署名 -> 署名挂牌 -> 邮寄证书 -> 发布生长日志(含用户评价) -> 领物订单 -> 分单或合单 -> 分拣 -> 出库 -> 打包 -> 打印单据 -> 生成电子面单 -> 物流揽件 -> 物流运输 -> 物流派件 -> 物流签收
普通认养事件 -> 风控拦截 -> 人工审核 -> 确认库存数量 -> 分拣 -> 出库 -> 打包 -> 打印单据 -> 生成电子面单 -> 物流揽件 -> 物流运输 -> 物流派件 -> 物流签收
因为
普通认养事件和普通订单没差别,所以就不考虑它了。
通过事件风暴,可以归纳出这么几个关联性较强的限界上下文。
风控:作为整个应用的入口,主要是为抵御了黄牛党、羊毛党和黑灰产等不法分子的侵袭,可以实现规则定义、事件拦截、人工审核和取消预订单功能。当然除了在拦截预订单这一块,还有其他的地方也需要用到风控,但为了简化,就不再体现了。认养:主要是用户署名、署名挂牌、邮寄证书、发布生长日志、用户评价、用户分享几块业务,这也是显著区别于其他产品的业务特色。其中,署名挂牌、邮寄证书、发布生长日志是由农场(也就是商家)来完成的。认养交付:提供领物订单、分单、合单等业务功能。仓储:因为属于初次开发运营,所以前期没有考虑自建或租用仓库,而是就地利用农场土地,搭建自己的处理车间,对认养的农牧产品进行分拣(包括净化、有证屠宰、冷藏等)、出库、打包、打印单据等操作。物流:这里如果再深入业务,就能发现其实它是由两个限界上下文组成的:能够调用不同物流接口的物流插件和不同物流公司的物流接口。物流插件属于是需要自行开发的支撑子域,而物流接口则应该归属于通用子域。
与各个限界上下文相关的所有的用户界面和命令,驱动了各种事件的执行,下面是部分认养的限界上下文。
因此,最终得到基于认养管理(核心子域)的全部限界上下文如下。

上下文映射关系
只要有了清晰的限界上下文,就可以据此得出各个部分之间的上下文映射关系了。

认养和认养交付之间是典型的发布-订阅(Publish-Subscribe)上下文关系,而且事实上,几乎所有的电商平台在订单生产这一块,都是这种模式。这种模式既不会遗漏任何一笔订单,又能起到流量整形和削峰的作用,还能实现不同子系统之间的解耦。因为
仓储所提供的服务都是固定的,通常也不会因为某笔订单而发生更改,所以它们之间可以采取遵奉者(Conformist)上下文模式。因为
风控不仅要应对认养交付业务的各种场景,还有交易中的各种退换货、运营中的各种活动场景,所以它不可能因为认养交付而改变接口功能,所以它们之间也采取的是遵奉者模式。同理,
认养交付和物流插件之间也采取遵奉者模式。至于
物流插件和第三方物流接口,纯粹就是API调用的关系,所以是典型的OHS(Open Host Service) + PL(Published Language)模式,而且可能还需要在物流插件侧增加ACL防腐层,来防止第三方物流接口变化时所引起的接口不可用问题。
难道认养交付和仓储、风控、物流插件这三者之间就只能采取遵奉者模式吗?当然不是,例如,认养交付和它们之间也完全可以采取发布-订阅模式,或者别的什么模式,这取决于各个开发者或者团队对于业务的理解。
至于哪种模式的执行效果更好,可以在测试或实际上线运行后通过不断调整来观察。
统一语言(部分)
理论是死的,人是活的,完全可以依据个人经验或业务推进的实际情况来决定什么时候统一语言。
因此,这一过程在整个DDD落地的过程中可以不断出现,毕竟召集业务专家们聚在一起不容易,指望一次会议就把所有的业务术语都给统一了,是不现实的。
统一语言的最大和最优先的目标就是要把业务方面的名词术语给统一了。
术语 | 说明 |
|---|---|
| 认养(或认领) | 本质上就是一种预售,通过图文、视频或直播的方式,让用户参与农牧产品的养殖过程,从而增加用户对产品健康、安全、美味的信心和兴趣,激发用户购买欲望 |
| 生长日志 | 由农场或商家自己发布的以图文或视频的形式记录农牧产品的生长状况,让用户可以以接近实时的方式观察其认养农牧产品。在具有一定规模的用户量后,再考虑增加直播形式(注意:这里的生长日志并非针对单个农牧产品而发布) |
| 用户探查 | 用户查看生长日志的内容 |
| 专属铭牌 | 用户通过图文或视频介绍的方式认养具体的农牧产品后,农场工作人员会定期将带有用户信息的铭牌「贴」到农牧产品身上作为认养标记,且终身有效 |
| 荣誉证书 | 以增值服务的形式为用户邮寄认养荣誉证书,如认养时一并购买仅需支付证书工本费,证书会随同农牧产品一同寄送;如认养活动结束且在发货后再购买,则需要额外支付证书邮资 |
| 认养分享 | 可以选择分享活动和分享认养后的农牧产品。例如,对于认养果树来说,假设果实成熟后可发货给用户的有10件(例如按1斤/件来算),那么在发货之前,用户可选择分享给微信好友0~9件(系统给用户至少保留一件不予分享),可以是同一位好友或不同好友。好友注册并领取分享之后,填写正确的收货地址,那么在发货时会按该用户填写的地址发送分享时指定的份数 |
| 普通认养订单 | 认养活动结束后,仍然通过平台购买可认养农牧产品,此时的订单就是普通认养订单。这种订单没有署名、挂牌和证书,和普通的订单没有差别 |
| 领物订单 | 认养活动结束后,事前参与认养活动的用户得到的农牧产品订单,此时无需支付额外费用 |
| 分单 | 所谓分单,是指在生成领物订单之后,当用户需要将部分农牧产品分享给好友时,会以订单的形式创建需要寄送的部分产品,这相当于是为领物订单创建了子订单(但子订单的价格为零) |
| 合单 | 如果某位用户认养了多个农牧产品,例如,既有果蔬,又有畜牧产品,那么在认养活动结束时,用户可以选择是否将这两份认养订单合并成一个,便于统一寄送 |
| 农场预处理 | 认养活动结束后,农场将用户认养的农牧产品进行处理后再通过物流发到用户手中。这里的处理指的是对蔬果类产品的采摘、净化、打包、装箱等活动,也包括对畜牧产品的有证屠宰、切割、分包等活动 |
| ...... | ...... |
上面是业务层面的名词术语,接着技术层面的命名规则。
当然,这种统一命名规则的行为也不可能是一次就搞定的,在后续开发过程中,尤其是在识别实体和值对象、聚合与聚合根的时候,还会再回过头来修改它。
| 术语 | 说明 |
|---|---|
| Renyang | 认养实体 |
| SignName | 认养署名 |
| Nameplate | 认养铭牌 |
| Certificate | 认养证书 |
| RenyangMessage | 发布认养事件时传递的消息 |
| Order | 订单 |
| OrderItem | 订单项,订单中的某一个商品或服务 |
| RiskIntercept | 风控拦截 |
| RiskEvent | 风险事件 |
| RiskAudit | 风控审核 |
| Warehouse | 仓库 |
| LogisticsPlugin | 物流插件 |
| LogisticsCompany | 物流公司 |
| ...... | ...... |
战略层面的技术决策
其实到这里,整个DDD的战略分析就全部完成了。
剩下的技术栈、应用架构、数据架构、治理架构和微服务的取舍只要团队意见一致就没问题了。
虽然说架构没有好坏,只有适用与否,但业界较为知名以及应用的比较多的,还是CQRS架构和阿里开源的COLA架构。
只不过对于初次使用DDD进行开发的个人或团队,在应用架构的取舍上可能还需要经历一个反复甑选的过程。
感谢支持
更多内容,请移步《超级个体》。
