本文思考了领域驱动究竟解决了什么事情
不妨让我们回到互联网初始的那个时间,那时候一切都简单朴素。我们编写简单的代码来控制一件事。
比如 if true then doThings
因为这样结构化的编程范式,我们写出了很长很长的代码,这些代码可以工作的很好。
我们有函数,它们可以将这些长长的代码进行分割,放在一个个文件里面。似乎没有任何问题。
时间慢慢的走,我们发现文件越来越多,我们引入来模块来将一些属于某个领域的文件集合打包。
让我们调整视角,看看模块内部的变化。
我们有了面向对象编程范式,大多数主流的编程语言都支持面向对象。如Java就是纯面向对象编程的。
面向对象提供很好的封装/多态/继承,让我们很容易编写出极度符合人类认知标准的代码。它将控制流从 文件的片段中移动到对象的行为上,我们称之为方法。
这是领域驱动的有力武器。
那么,领域驱动到底解决来什么问题呢?
领域驱动顾名思义就是通过领域设计来驱动开发,简单的来讲,就是在开发中引入领域概念来屏蔽调计算机领域和 业务领域的细节,让开发者和领域专家(任何对某个领域有丰富知识的人)协同开发的一种软件架构模式。
第一个原因
我们当今面临的业务复杂,开发人员往往不具备业务的领域知识,领域专家不懂技术,在沟通上往往会存在障碍。 因此领域驱动在一定程度上会强迫参与者进行知识的互相分享。
第二个原因
同时第二个重要的原因是,方便编写可维护性高的代码。 领域的知识往往是静态的。比如一个电商的下单流程,往往是固定的。 支付-检查锁定库存-生成订单。
引入领域驱动,可以更利于编写有业务价值的代码。
第三个原因
第三个重要的原因领域知识的沉淀,往往这些领域知识都是可以复用的。这意味着可以跨项目共享,减少开发的工作量。 领域天生具有极强的边界。所以可以拒绝不合理的系统改造。减少系统的熵。
在如今,团队协作/跨团队协作的背景下,领域驱动开发可以很好的在保证系统边界的前提下,拥有良好的代码维护性和扩展性,增强团队的领域知识。
当然,领域驱动是一种架构模式,跟语言无关,跟编程范式无关,这就意味着,如果不是面向对象语言,也可以做到领域驱动。
领域驱动有几个非常核心的概念:实体、聚合根、值对象、界定上下文、资源库、领域服务、工厂、领域事件。
这些概念是一种指导和约束,用来思考和构建领域知识。在使用领域驱动开发落地的时候,一个前提是沟通。 通过一些有意义的会议和讨论来得出一个系统的领域边界和知识。 实体就是一个个知识的代名词。
一些编程语言都支持属性访问,将实体的属性暴露出去不会有任何问题,但是,它并不代表领域知识。比如订单的一个价格的字段,直接抛出去而不用一个行为。
甚至在一定程度上更简洁。但是问题是,当通过某些订单拥有优惠券的时候,你必须得通知全部使用了这个字段的人,我引入了优惠券,你需要减去某个金额,
长时间下去,系统将难易维护。
内聚力是领域驱动的内功,如果理解领域知识使其高度内聚,是领域驱动设计的关键。
当然,领域驱动并不是银弹,我们需要考虑输出的产品是什么,有无团队协作,是否有领域专家,以及项目的其他因素。
并不是所有的产品都适合领域驱动设计。很多时候,我们系统更应该考虑如何模块化