0
点赞
收藏
分享

微信扫一扫

浅析DDD

冬冬_79d4 2022-01-30 阅读 94

最近在做一些微服务相关的设计,内容包括服务的划分,Restful API的设计等。其中比较棘手的就是Service的职责划分:如何抽象具有统一业务范畴的Model,使其模块化,又如何高度提炼并组合多模块,使得业务可独立服务化。为了找寻答案,看了不少书籍和博客,在DDD中找到了一些思路,个人觉得受益匪浅,或许也可以受用于大家,特分享于此。

什么是DDD

软件开发不是一蹴而就的事情,我们不可能在不了解产品(或行业领域)的前提下进行软件开发,在开发前,通常需要进行大量的业务知识梳理,而后到达软件设计的层面,最后才是开发。而在业务知识梳理的过程中,我们必然会形成某个领域知识,根据领域知识来一步步驱动软件设计,就是领域驱动设计的基本概念。

听起来这和传统意义的软件开发没啥区别,只是换了点新鲜的名词而已,其实不然。

软件开发 VS DDD

建立领域知识(Build Domain Model)

说了这么多领域模型的概念,到底什么是领域模型呢?以飞机航行为例子:

尽管看起来还是很简单,但我们已经开始一步步的在建立领域对象和领域模型了。

可如何形成这种通用语言呢?其实答案并不唯一,确切的说也没有什么标准答案。

a)UML

b)伪代码

模型驱动设计(Domain Driven Design)

模型关系图(Model-Driven Design)

领域驱动设计中的模型关系图如下:

层结构(Layered Architecture)

实体(Entity) & 值对象(Value Object)

服务(Services)

当我们在分析某一领域时,一直在尝试如何将信息转化为领域模型,但并非所有的点我们都能用Model来涵盖。对象应当有属性,状态和行为,但有时领域中有一些行为是无法映射到具体的对象中的,我们也不能强行将其放入在某一个模型对象中,而将其单独作为一个方法又没有地方,此时就需要服务.

服务是无状态的,对象是有状态的。所谓状态,就是对象的基本属性:高矮胖瘦,年轻漂亮。服务本身也是对象,但它却没有属性(只有行为),因此说是无状态的。

PS:这与我们常说的服务器的状态是两个概念,无状态的服务器是指,对服务器来说每次接收到的HTTP请求都像是客户端第一次发送的一样;而有状态的服务器就会存储客户端的状态,常见的就是Cookie&Session

服务存在的目的就是为领域提供简单的方法。为了提供大量便捷的方法,自然要关联许多领域模型,所以说,行为(Action)天生就应该存在于服务中。

服务具有以下特点:

PS:不要随意放置服务,如果该行为是属于应用层的,那就应该放在那;如果它为领域模型服务,那它就应该存储在领域层中,要避免业务的服务直接操作数据库,最好通过DAO。

模块(Moudles)

聚合(Aggregates)

工厂(Factories)

仓库(Repository)

结束语
CQRS本身也是一种架构模式,但更多的是它被应用在DDD中。因为DDD中有工厂和仓库来管理领域模型,前者主要用于创建,而后者则用于存储。这就表明在DDD中是默认将读写分离的,DDD似乎就天生和CQRS有着无缝的链接。

CQRS往往要求数据库进行读写分离,具体来说,所有的更新操作均无返回值(void),而读操作才返回对应的值。在实现CQRS时,又和事件源(Event Source)相结合,以下是一个简单的交互过程:

客户端发起一个请求,服务端将其映射为一个命令,该命令会从仓库中读取一个相关的聚合,对该聚合进行操作,将会生成一个事件源,将该事件发送出去,接收方收到消息后(并不是立刻)将会更新领域对象,完成一次更新操作。

在此基础上,还有称之为六边形的架构风格,它将DDD的领域模型包裹在内,外围含有多种适配器来适配各种通信方式,总体来说,我觉得无论是DDD,CQRS还是六边形,都是一种架构的设计思路,没有绝对的优势,同时也有各自的复杂度,并不容易理解,但有时在软件设计时,不妨多学习一下其中的小细节和思路,必然能够有所收获。

至于能否应用?如何应用?,笔者只能说不能生搬硬套,需要有一定的实践经验才能去尝试,一般情况下,结合项目特点,能适当的灵活采用其中的设计思路即可。

举报

相关推荐

0 条评论