苏眠月|DDD as Code:如何用代码诠释领域驱动设计?( 四 )


既然是描述各个BoundedContext关系 , 必然会涉及到关联关系 , 如DDD推荐的Partnership([P]<->[P])、Shared Kernel([SK]<->[SK])、Customer/Supplier([C]<-[S])、Conformist(D,CF]<-[U,OHS,PL])、Open Host Service、Anticorruption Layer([D,ACL]<-[U,OHS,PL])、Published Language等 , 详细的介绍大家可以参考DDD图书 。 这些对应关系都有对应的缩写 , 就是括号内的表述方法 。 这里给出关联关系Cheat Sheet说明图:
苏眠月|DDD as Code:如何用代码诠释领域驱动设计?图源:
如果你自行画图来表达这些关系 , 一定有非常多的工作量 , 细致到箭头类型 , 备注等 , 不然会引发误解 。 这里我们就直接上ContextMapper DSL对ContextMap的描述方式 , 代码如下:
ContextMap UserContextMap {type = SYSTEM_LANDSCAPEstate = TO_BEcontains AccountContextcontains UserTagContextcontains PaymentProfileContextcontains SnsProfileContextcontains ProfilesContextcontains UserLoginContextcontains UserRegistrationContextUserLoginContext [D]<-[U] AccountContext {implementationTechnology = "RSocket"exposedAggregates = AccountFacadeAggregate}ProfilesContext [D]<-[U] UserTagContext {implementationTechnology = "RSocket"exposedAggregates = UserTags}UserRegistrationContext [D,C]<-[U,S] UserTagContext {implementationTechnology = "RSocket"exposedAggregates = UserTags}UserRegistrationContext [D,C]<-[U,S] SnsProfileContext {implementationTechnology = "RSocket"}}大家可以看到Map图中包含的各个BoundedContext名称 , 然后描述了它们之间的关系 。在关联关系描述中 , 涉及到对应的描述 。前面我们说明BoundedContext为Domain的具体系统和应用的承载 , 所以涉及到对应的技术实现 。如HTTP REST API、RPC、Pub/Sub等 , 如blog系统为Medium的话 , 那么implementationTechnology = ”REST API" 。还有exposedAggregates , 表示暴露的聚合信息 , 如class对象和字段 , 服务接口等 , 方便通讯双方做对接 , 这个我们会在BoundedContext中进行介绍 。
BoundedContext
在ContextMap中我们描述了它们之间的关联关系 , 接下来我们要进行BoundedContext的详细定义 。 BoundedContext包含的内容相信大多数同学都知道 , 如Entity ,ValueObject , Aggregate , Service , Repository、DomainEvent等 , 这个大家应该都比较熟悉 。 这里我们给出一个ContextMapper对BoundedContext的代码 , 如下:
BoundedContext AccountContext implements AccountDomain {type = APPLICATIONdomainVisionStatement = "Managing account basic data"implementationTechnology = "Kotlin, Spring Boot, MySQL, Memcached"responsibilities = "Account", "Authentication"Aggregate AccountFacadeAggregate {ValueObject AccountDTO {long idString nickString nameint statusDate createdAtdef toJson();}/* AccountFacade as Application Service */Service AccountFacade {@AccountDTO findById(Integer id);}}Aggregate Accounts {Entity Account {long idString nickString mobileString ^emailString nameString saltString passwdint statusDate createdAtDate updatedAt}}}这里对BoundedContext再说明一下:

  • BoundedContext的名称 , 这个不用说啦 , 这个和ContextMap中名称一致 。