在我看来,业务领域层是一个互联网公司最核心的部分,它是一个公司业务模式-技术化的载体,会有非常多的职能方一起参与进行开发,比如公司的业务架构师、产品经理、其它兄弟部门。 但随着参与人多了,沟通是一个问题,特别是岗位职能完全不同,鸡同鸭讲、对牛弹琴,而对于复杂的业务、关联方更多,沟通成本可想而知。DDD就是面向这种场景下的解决方案,它是对业务需求的高度抽象,根本目的是帮助我们理解和分析业务,在多方沟通、交付中,统一建模理解,以指导进一步的技术实现。
作者:程波
掌门教育业务系统前端架构师
软件开发架构演化与DDD起源
单体服务架构:大概10年前,我在武汉工作的时候,甲方客户购买我们的产品,一般都是连着设备一起购买,一套软件系统,一台惠普或者戴尔的企业级服务器,再加一个黑色的铁盒,销售部可以卖小几百万左右、外加每年维护费用,这就是一个非常典型的单体服务开发、运作的方式。
SOA服务化、微服务架构:前端开发同学普遍离业务域结构比较远,一般比较难真正意义上去理解服务化与微服务,我个人对微服务和SOA区别的理解,SOA服务化,往往侧重某一类具体业务场景下功能的实现,它必须有一个明确的业务场景来做支撑。微服务更加侧重类似区块链这种去中心化结构,它的开发、部署、发布等等可以完全独立隔离。
中台化架构:中台化除了包含SOA、微服务这个技术结构以外,业务场景层面,它更推崇信息智慧化,大数据、深度学习、神经网络、人工智能,他的原材料可能是用户个体数据信息,但作用结果并不是直接反哺在单个应用个体,而是交给公司运营、市场、供应链等等兄弟平台,兄弟部门来做下一步决策。
中台化最典型的场景是类似金融、保险、电商等行业,我做过一个生鲜次日达项目,生鲜特别是肉类,当用户量上来了,采购少了补采来不及,采购多了,当天就坏了,所以,对于我们技术部来说,最大的挑战在于,为什么我们能提前一天就知道5吨肉刚好就能卖完,我们能够实现这样的业务场景支撑,就是信息智慧化带来的结果。
DDD(领域驱动设计)起源于2004年前后,却随着SOA、微服务开始普及。
DDD应用场景
在我看来,业务领域层是一个互联网公司最核心的部分,它是一个公司业务模式-技术化的载体,会有非常多的职能方一起参与进行开发,比如公司的业务架构师、产品经理、其它兄弟部门。
但随着参与人多了,沟通是一个问题,特别是岗位职能完全不同,鸡同鸭讲、对牛弹琴,而对于复杂的业务、关联方更多,沟通成本可想而知。DDD就是面向这种场景下的解决方案,它是对业务需求的高度抽象,根本目的是帮助我们理解和分析业务,在多方沟通、交付中,统一建模理解,以指导进一步的技术实现。
DDD的优势
项目健壮性:对于技术同学来说,谈到代码健壮性,我们往往会提到高内聚、低耦合,这对于不少开发同学来说,在业务开发最开始的时候,并不是什么大问题,在我看来,健壮性真正的挑战来源于,是在不断变化的业务需求、和开发时间之间的冲突下,日积月累形成的,而DDD推崇的是,对业务需求的高度抽象,因此,它可以在最根本上减少我们业务需求变化的可能性,从而带来业务健壮性上的提升。
业务灵活性:对于DDD设计架构的项目,因为核心实现、边界切割非常清晰,在很多业务场景下,胶水层或者controller层的实现,类似于积木堆砌,因此可以预见的是,在这种模型下,只要核心服务不发生重大变更,它的业务灵活性将非常强韧。
工程易维护:DDD只是一种设计思维,它的作用场景主要在于业务架构师、产品经理、技术开发等等多方协同工作,因此,在工程维护性上,相对于我们常说的代码可读性等等,它可以影响更多兄弟部门,可谓是降维打击。
DDD对前端的挑战
前端职能面向交互:对于前端开发同学而言,我们主要的工作量在于交互层面的实现,很少会直观的去关注,在一个业务场景下,为什么用户可以去抽奖,为什么用户抽中后,可以通知用户领奖,对于前端开发而言,对于一个业务闭环背后的“为什么”关注比较少。
设备、场景裂化严重:我以前做过一个需求,也是一个抽奖的功能,但是,要求在微信端、非微信H5端、PC端、还有微博端都做实现,这里就产生了一个问题,如果我的业务逻辑在C端实现,同样的代码,我必须实现很多份,一个小小的变动,我可能需要发版多次,最终,方案逻辑只能是放在server端,所以,这是设备、场景裂化带来的局限性。
业务沉淀驱动力不足:受限于我们在业务闭环上的关注度、设备、场景裂化,这就导致我们很难再抽出额外的精力去关注业务沉淀。
掌门教育DDD实践
我们团队在一起沟通Mapping项目需求的时候,举过一个例子,未来我们业务应用的开发方式,应该像带烟囱的工厂,工厂厂房是聚合平台,它是一个黑盒,厂房上面一个个独立的烟管,就是我们一个个独立的应用出口。
比如,*机构提供了一个查询用户身份证的API,A、B、C三个游戏公司的应用,对接实名认证功能,或者用户充值,对接支付宝、微信的支付功能,他们之间的业务界限应该非常清晰。
因此,对于我们做规则模块来说,其中非常核心的部分,就是如何帮助我们的C端开发者,做好业务领域边界划分。
其次,我们Mapping项目开发过程中,最开始在做状态模块、决策模块,或者流程模块、数据处理模块的时候,我一直在考虑是否要合并做,因为它们之间的关联性非常强,最终我们选择分开来实现,后来在做Mapping二期需求设计的时候,就非常庆幸之前的选择,因为我们发现新的模块对一期部分功能模块依赖也很强,如果一开始我们设计没有做好分离,我们的引用成本就很高,需要做多层不同数据字段值校验,而分离干净后,如果引用部分是一个StateNode模块,或者是一个Schema模块,我们可以只对类型做校验,而不需要做字段数据值校验,这能够帮助我们规避很多无意义的问题。
总结与思考
1.业务高内聚、低耦合:未来,我们技术开发同学,将不可避免的,需要去面对更复杂、更多变的业务需求,应对之道,在我看来,除了我们在做代码实现的时候,需要采用更合理的设计模式、分层开发之外,我们更需要能够紧跟公司具体的业务场景,以业务领域驱动为沟通基础,对齐一条线上的OKR,才能做到事半功倍。
2.我前几年看过的一个数据,大概意思是,我们现在每天产生的数据,可能都比21世纪以前的数据量加起来都多,这么海量的数据,背后代表的将是海量的业务场景,可想而知,我们的业务需求多样性也将是海量的,这也就对我们如何能够快速理解、消化、并对业务进行技术实现,带来很大的挑战,但在精细化运作的时代,一个公司不可能像过去那样单打独斗就能有一番作为,一定是多人、多方协同下去实现业务,从这个方面出发来看,我觉得DDD大有可为。
3.之前跟朋友开玩笑,举过一个例子,我说以前大家玩Dota,会补刀、会选择合适时机放技能,就算厉害了,过了两年,如果不会补刀、择机放技能,就是菜鸡了,游戏还是同一个游戏,但是有了沉淀、有了积累,慢慢大家就拉开差距了,DDD对于我们技术开发同学来说,其实是一个与公司业务发展共同成长中,一个很好的桥梁。