业务背景
几个月前,我参与引导了一个大型通讯企业某个技术团队的DDD实施过程。这个团队的主要业务是通过底层通讯设备内置的探针不断采集海量数据,然后进行一系列的数据操作,从而对网线网络站点等网元进行评估与优化,同时包含一些网络规划的功能。覆盖的网络场景包括覆盖分析、话务分析、用户分析、高铁评估 、业务质量管理、客户感知保障、商业智能支持等。底层通讯设备采集的数据量非常巨大,基本上都是以GB为单位,这与以往的作业类系统不同,是一个典型的以数据处理分析为主的系统。项目类型上的不同也导致后面在DDD建模过程中,遇到了一些以往没有遇到过的问题。
建模过程
经过与客户的讨论,我们初步选择了楼宇分析这个业务领域进行试点建模。
在《DDD实施过程中的点滴思考》这篇文章里我也提到,我一直想在建模开始的时候就把业务问题域梳理清楚,明确核心域,通用域和支撑域;然后就核心域进行建模,接着把模型放回核心域验证是否能解决业务问题。所以这一次,我一上来就先使用名词动词法对业务进行梳理。一般来说,名词动词法就是让客户通过简单的几句话描述业务要解决什么样的问题,然后注意其中的关键名词与动词。
通过名词动词法梳理的业务领域如下:
由于某些词语涉及到客户信息,所以被mask了。总体来说,通过这种方法,能把某个业务下的细分场景捋清楚,但这不是最关键的,最关键的是当把细分场景梳理出来后,对核心域,通用域,支撑域的识别与区分。这非常重要,因为传统意义上来说,DDD认为核心域代表了产品的独特的核心竞争力,团队只应该对核心域进行建模,并把主要精力投在核心域的开发工作上,而对于通用域与支撑域,DDD主张通过购买或者外包来实现。具体的识别过程,需要客户的领域专家一起参与讨论。但是实际上,在之前的项目过程中,我们还是会把其余两个域的模型都建了。这次也一样。
按照传统套路,当核心域识别出来后,后面就是事件风暴大法了。
熟悉事件风暴的同学可能就已经看出与标准的事件风暴有什么不一样了。“数据模型”这个概念在标准的事件风暴里面是没有的。那为什么这里会出现这么一个概念呢?按道理说,事件风暴完了后,就应该是识别聚合了。问题就出现在这里。当时我们发现,根据以上事件流无法识别聚合。因为聚合的一大特征是它是有状态的,而在这个场景下,事件流里面的都是没有状态的数据。做过大数据或者数据分析类项目的同学可能清楚,这类项目对数据的处理就是数据采集、解析、清洗、拼接、过滤等步骤,在这个过程中,数据是没有状态的,可以认为每一步产生的数据都是全新的数据。因此这里再沿用传统的聚合概念就不合适了。所以这类我们引入了“数据模型”这个概念。可以认为,数据模型就是数据分析类项目里的“聚合”。
基于这个共识,我们可以往前再走一步,整理一下数据模型的事件与命令,
这里区分了数据面和控制面。数据面主要负责对数据的处理流程,控制面主要是传统作业,负责控制层面的工作,所以它会出现传统意义上的聚合。例如图中的“特征库构建任务”。
建模到这一步,下一步应该就是限界上下文了。但是,这里我们先不着急。由于事件流里面流动的是数据模型,所以事件流即数据流,我们何不看一下数据的流动呢?所以我们基于数据流再梳理了一次:
这一下数据的流动就清晰多了。然后下一步才做的限界上下文:
我们把限界上下文投射回最开始时通过名词动词法梳理的业务领域,验证是否能解决业务问题。这一步同样需要业务领域专家一起讨论。
后记
后面因为某些原因,项目终止了。我们的建模工作也结束了,没法再继续验证模型的可用性。但是还是把楼宇分析业务场景的建模基本完成了,后面其实就是实现域的事情。 在实现层面,客户热衷于微服务,但坦率来说,微服务架构是否真的适合这种数据分析类项目,我个人是持保留意见的。把微服务应用于GB级的数据传输,可想而知挑战有多大。
说回这次建模。通过这次建模得到的模型是否能很好的指导后面的实现落地,这很难说。毕竟把DDD应用于大数据或者是数据分析类项目的建模,我还是第一次做,业界做的也不多。方法论需要更多的项目来整理,提炼与验证。通过这次建模,我的总结如下:
1. 建模前通过某些方法(如动词名词)把业务领域梳理清楚是可行的,这可以避免得到解决方案再来反推问题域的尴尬。我们要做的只是把解决方案投射回业务领域验证就行。
2. 对于大数据或数据分析类项目,可认为数据模型即聚合。
3. 事件风暴或许并不适合这类项目,可能基于数据流建模的方法更合适。将来如果还有类似的项目,我可能就会直接基于数据流建模了。当然这个需要更多的项目去提炼验证。
4.DDD完全适合于这类项目,只是具体的落地方法可能需要调整。因为DDD的核心理念是业务领域驱动架构设计,任何系统架构都必须随业务架构变化而演进。借用我从EA培训听到的一句话,无业务不IT,无架构不解决方案。套在DDD上,就是无DDD不架构。