1.战略设计
1.1 领域
首先,既然我们的
DDD
是领域驱动设计。那么领域必然是我们的重中之重,
那么什么是领域呢?
一个领域本质上可以理解为就是一个问题域,只要是同一个领域,那问题域就相同。所以,只要我们确
定了系统所属的领域,那这个系统的核心业务,即要解决的关键问题、问题的范围边界就基本确定了。
通常我们说,要成为一个领域的专家,必须要在这个领域深入研究很多年才行。因为只有你研究了很多 年,你才会遇到非常多的该领域的问题,同时你解决这个领域中的问题的经验也非常丰富。
同时大家从字面上的意思也能够知道,
领域其实就是我们的范围
,而范围实际上就是我们的边界,我们 做什么,做到什么程度,最低多少 ,最高多少。而范围定义下来之后,我们根据这个范围去计划我们要 做的事情。这不就是领域驱动设计吗??比如你现在要去做一个电商网站,那么你的进货,优惠规则,物流仓储,销售报表,这些直接跟你的业 务相关的东西都归属于领域,而所谓的领域驱动设计就是你需要预先把领域中所涉及到的数据,流程以 及业务规则搞清楚,然后再通过面向对象的方式为他去建立一个模型,这个模型就叫做领域模型。我们再去选择合适的技术去对他进行实现。
1.2 子域
我们好像只需要建立一个大的领域模型,而建立 完成这个大的领域模型之后,我如果说有一些小的功能点希望进行修改,这个时候我应该怎么操作呢? 因为本身我们的DDD
就是用来处理高度复杂的领域的设计思想,你都高度复杂了,我还用一个东西把你 装起来。说要用一个领域将你全部装起来,是不是有点不合理啊。
那么我们的
DDD
是怎么做的呢?我们的
DDD
使用了一种非常简单的方式,大事化小,既然你整个领域太 过于复杂,业务太过于分散,那么这个时候我们做一个拆分如何,你的电商系统很复杂,那么我单独将他拆分成比如一个个的模块,订单,商品,库存是不是会好处理一些呢?甚至我们的模块还能进行细分,比如库存,可以分为本地库,异地库,三方托管库。当然,这里只是类比,因为我们还在学概念的阶段。这里希望大家能够去理解这个概念。这一个个的模块,实际上在我们的领域驱动设计中还有好听的名字,叫做子域。 那么这个时候,我们可以一个个的去研究我们的子域,当我们所有的子域搞定了之后,是不是我们整个 领域也就搞定了。当然是这样,因为原本我们的子域集合,就是我们的领域嘛。聊到这里,大家是不是 觉得有点像微服务了,当然,本质上我们的微服务架构与领域驱动模型没有任何的关系。一个是思想, 一个是架构风格。但是他们的目的都是一致的,都是希望能够将复杂的事情简单化。 那么随着我们划分子域,我们发现我们的子域的划分我们已经慢慢的掌握了,但是我发现不同的子域重要性以及功能属性完全不一样。所以我们又会将子域分为核心域、通用域和支撑域。 为什么要将这些子域进行单独的定义呢?实际上是因为我们的公司在建设项目的时候,会有非常多的限制,比如预算,比如人员,但是这些资源
我如果平均分配在每一个子域,就有可能会导致其中一些子域关注度不够。比如你们公司的核心业务。 可能就会因为得不到足够的资源,导致项目失败。 所以,我们对应不同的子域应该采取不同的态度。 其实很多的同学会觉得,相同行业的领域模型是可以复制的,但是我告诉大家,这是错误的。
比如淘宝跟京东。一个是
C2C
,一个是
B2C
。那么,显而易见的,
C2C
更加注重于服务,当然,这 是对于买卖双方的服务。所以,你们会发现,淘宝所有的一切,都是为了保证卖家能够好好的卖出 去货,买家能够把货收到。那么这样一单完成,钱到手。所以,我们还会对于商品进行展示,甚至 直播展示,所以会有淘直播。所以这种模式核心在交易保证。 而B2C
呢,其实卖的是口碑,如果说
C2C
你需要直接保证交易,而
B2C
实际上会更加关注产品的质量,为什么这么说呢?因为我们的B2C
实际上如果你产品质量不好,那么我就会直接找到你的
B
方,也就是商家端。所以他的生命线实际上是质量。包括同学们聊起京东,肯定第一反应是质量。
这已经做为了产品属性标签。
可能有同学会说,淘宝就不用做质量了吗?或者说京东就不做交易保证吗?所以这就是我们的兼
顾,我们的业务力量需要放在刀刃上,并不是说其他的地方我们不会兼顾。
这个时候可能有些同学会有一些问题,老师,京东跟苏宁是不是同一种商业模式啊,我去进行设计
的时候能不能进行同类分析啊。
包括我们去进行子域划分的时候是不是可以
Copy
。
这里我告诉大家,肯定是不行的。苏宁实际上强调的是线下选货,线上卖货,他们的核心在于线
下。是由典型的线下往线上走,这种方式其实看重的是线下的服务,包括他们核心的源头在于你线
下要有足够的流量。你才能慢慢打通线上。
所以,其实大家会发现,我们的商业模式的不同,我们的侧重点不一样。所以我们去进行软件设计的时候方式也会不一样。如果是中小公司的架构,跟不懂技术的老板应该聊的是这些东西,而不是具体的技术栈。
核心域
那么什么是核心域呢?实际上他就是当前领域的最核心的竞争力,也就是业务核心,
核心域是整个业务系统的核心,所有的业务都要围绕着核心业务域展开。如何明确核心域呢?
比如我们的淘宝,按照淘宝的模式,那么在交易保证的情况下,交易双方的属性必定就是我们的核心, 比如返利,比如商户系统。 而京东则不一样,在京东自营模块而言,他们更加注重质量,这里的产品质量保证实际上不仅仅是产品 本身,产品运输过程中也会导致质量问题。包括采购系统,包括仓储,物流,供应链才是他们的核心。
通常明确核心的方式是
精炼业务域
。精炼是一个持续的过程,具体来说有以下几种方式:
领域愿景说明(
Domain Vision Statement
)
比如某里,实际上他们的愿景,让天下没有难做的生意。就充分说明了他们的愿景。
其实这里有同学可能会不理解,说白了,就是你们项目最初立项的目的是什么,目标是什么。为什么要 做这个项目。 很多同学会认为,我们立项的目的是赚钱。可是我用什么手段赚钱呢?比如客户交易手续费,或者说信息差,或者流量费用,打广告。
突出核心(
Highlighted Core
)
我们通过
“
领域愿景说明
”
可以明确什么是核心域,但这是从一个较为宽泛的角度对核心域进行说明
的。我们明确核心域的目的是为了形成
核心
领域模型,此时我们需要突出核心。
突出核心域中的领域模型有两种方式:
精炼文档
标明核心(
Core
)
问题:
1.
文档可能得不到维护
.
2.
文档可能没人阅读
.
3.
由于有多个信息来源
,
文档可能达不到简化复杂性的目的
.
不过最起码你有文档,才能够让需要接手项目的人能够去找到参考物
内聚机制(
Cohesive Mechanism
)
这个是什么意思呢?其实当你的项目越来越大的时候,你的修改可能会越来越多,这个时候你的代码 可能会在原本的代码上增加很多,那么就有可能导致你原本的代码
分离的核心(
Segregated Core
)
将核心域中的非核心元素(模型)分离出去。
将非核心域中的核心元素(模块)移动到核心域中。
非核心的动作其实你可以稍微的关注度放低,比如物流,其实不属于交易保证范围之内,那么他就
可以做为我们的支撑子域。
抽象核心(
Abstract Core
)
当不同模块的子领域之间有大量交互时
,
要么需要在模块之间创建很多引用
(
在很大程度上抵消了划
分模块的价值
),
要么就必须间接的实现这些交互
,
而后者会使模型变得晦涩难懂
.
因此
,
把模型中最基本的概念识别出来
,
并分离到不同的类
,
抽象类或接口中
.
设计这个抽象模型
,
使之能
够表达出重要组件之间的大部分交互
.
把这个完整的抽象模型放到它自己的模块中
,
而专用的详细的
实现类则留在由子领域定义的模块中
.
核心域的范围并不一定是一次就能确认的,可能需要迭代很多次,每一次都有可能扩大或缩小。
通用域
接下来就是我们的通用域,通用域这个概念其实也很好理解,整个领域都能够用到的子域,比如我们的 认证,权限等等相关的模块,这就是我们的通用域,你不需要定制化,只要能够去解决问题就OK
了。
支撑域
什么是支撑域呢?
支撑域实际上就是不包含核心竞争力的功能,也不包含通用的功能,但是又是必须的支撑。比如限时拼 团功能,没有他电商网站能够正常运行吗,可以,但是为了配合活动,他能够辅助我们成单。但是在某 些专门的拼团电商中他又是必须的核心。所以我们必须根据当前的情况来进行分析。
总结:
你会发现,领域驱动的核心思想就是将问题慢慢细化,同时找出最核心的问题点,倾斜资源保证核心资 源不出问题,同时也可以通过领域的细分,去慢慢的缩小我们的子域所要解决的问题,并且构建合适的 领域模型,到这一步为止,其实他跟我们的微服务都是有异曲同工之秒的。