首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

领域驱动设计 (DDD) 实践之路(一)

2020-04-28

一般,咱们期望将子域一对一地对应到限界上下文。这种做法显式地将范畴模型别离到不同的事务板块中,并将问题空间和处理方案空间交融在一起。

可是在实践中,这种做法并不总是或许的,想像一下,谁没有保护过“毛线团”体系,现在咱们就要凭借边界上下文来安全的、合理的、快速的理顺这堆交错不清的联系。

许多书本或许文章解说DDD,总是说杰出应该怎样构建代码包结构,运用什么技能结构。我以为这是不完全适用的,所以我会花较多时刻来论述一下怎么凭借边界上下文来理顺这堆“毛线团”。

我直接运用了《完成范畴驱动规划》的相关章节的配图,权当是我对这个图的注释吧。

留传的电子商务体系是个典型的“大线团”,咱们依照经历将其在逻辑上拆解为:产品目录子域、订单子域、发票子域,当然你也能够拆解出更多的子域,乃至将产品目录子域持续向下分化为类目子域、产品子域。别的还有一个专门用于库存办理的库存体系、以及用于出售猜测的猜测体系。

由于前史原因电商体系里边也存在物流相关的事务逻辑,一起物流又不可避免的作用于库存逻辑之上。而往往最难以掌握的便是这部分相交的当地,这才是实践的项目场景,咱们一般做法是将其归并为一个新的履约体系,作为一个支撑子域去辅佐首要的电商体系。

当然,跟着事务不断发展,咱们的履约形式、库存类型越来越杂乱,咱们考虑将其再向下分化为履约体系2.0、库存体系2.0。

中心便是咱们能够在概念上运用多个子域来分化较大的边界上下文,也能够将多个涣散的边界上下文包含在同一个新的子域傍边,终究做到“子域和边界上下文一一对应”。我个人觉得,这个进程是最检测内功心法的当地。

我直接运用了《完成范畴驱动规划》的相关章节的配图,权当是我对这个图的注释吧。

留传的电子商务体系是个典型的“大线团”,咱们依照经历将其在逻辑上拆解为:产品目录子域、订单子域、发票子域,当然你也能够拆解出更多的子域,乃至将产品目录子域持续向下分化为类目子域、产品子域。别的还有一个专门用于库存办理的库存体系、以及用于出售猜测的猜测体系。

由于前史原因电商体系里边也存在物流相关的事务逻辑,一起物流又不可避免的作用于库存逻辑之上。而往往最难以掌握的便是这部分相交的当地,这才是实践的项目场景,咱们一般做法是将其归并为一个新的履约体系,作为一个支撑子域去辅佐首要的电商体系。

当然,跟着事务不断发展,咱们的履约形式、库存类型越来越杂乱,咱们考虑将其再向下分化为履约体系2.0、库存体系2.0。

中心便是咱们能够在概念上运用多个子域来分化较大的边界上下文,也能够将多个涣散的边界上下文包含在同一个新的子域傍边,终究做到“子域和边界上下文一一对应”。我个人觉得,这个进程是最检测内功心法的当地。

上面咱们现已说了会拆解出来新的子域,意图使“整齐洁净”的边界上下文能够一对一的处理这个子域对应的问题空间,可是跟着拆解就必定导致“相关联系”。由于要处理问题空间,有必要运用对应的子域,你能够把它拆解出去,可是它一直存在于依靠网中。

咱们通用的做法是在相交的当地,界说接口。由支撑的边界上下文去完成,能够做到支撑上下文的插拔式切换。这儿仍然是咱们着重的“依靠笼统”“解耦”。

2、Repository

“关于每种需求进行大局拜访的目标,咱们都应该创立另一个目标来作为这些目标的供给方,就像是在内存中拜访这些目标的调集相同。为这些目标创立一个大局接口以供客户端拜访。为这些目标创立增加和删去办法……

此外,咱们还应该供给能够依照某种指定条件来查询这些目标的办法……只为聚合创立资源库”引证自《范畴驱动规划》。咱们和我的疑问相同,Repository是什么?DAO与Repository什么区别?为什么需求Repository?

它的存在让范畴层感觉不到数据拜访层的存在,它供给一个相似调集的接口供给给范畴层进行范畴目标的拜访。Repository 是仓库办理员,范畴层需求什么东西只需告知仓库办理员,由仓库办理员把东西拿给它,并不需求知道东西实践放在哪。其中心仍是“解耦”,所以咱们应该清晰范畴层只应该运用Repository获取目标。

我的了解是这样,你能够将Repository当作 DAO 来看待,可是请注意一点,在规划Repository时,咱们应该选用面向调集的办法,而不是面向数据拜访的办法。这有助于你将自己的范畴当作模型来看待,而不是 CRUD 操作;Repository是面向范畴的,Repository界说的意图不是DB驱动的,Repository办理的数据的最小粒度是聚合根,这两点和DAO有很大不同。

一般咱们主张把Repository界说为一个调集而且只供给相似调集的接口,比方Add,Remove,Get这种操作。一言以蔽之,咱们要用调集的思想来操作聚合根,而不是传统的面向DB的CRUD办法。

以下是代码示例:

package zwb.ddd.repository.sample.domain;

import zwb.ddd.repository.sample.domain.model.BaseAggregateRoot;

import java.util.List;

/**

* BaseAggregateRoot范畴模型的基类,BaseSpecification适用于较为杂乱的查询场景。

* @author wenbo.zhang

* @date 2019-11-20

*/

public interface IRepository T extends BaseAggregateRoot, Q extends BaseSpecification {

T ofId;

void add;

void remove;

List T querySpecification;

}

package zwb.ddd.repository.sample.domain;

import zwb.ddd.repository.sample.domain.model.BaseAggregateRoot;

import java.util.List;

/**

* BaseAggregateRoot范畴模型的基类,BaseSpecification适用于较为杂乱的查询场景。

* @author wenbo.zhang

* @date 2019-11-20

*/

public interface IRepository T extends BaseAggregateRoot, Q extends BaseSpecification {

T ofId;

void add;

void remove;

List T querySpecification;

}

热门文章

随机推荐

推荐文章