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


如花首先将会员先划分为几个Sub Domain , 如处理账号相关的Account , 处理会员打标的UserTag , 处理支付方式的PaymentProfile , 处理社交平台集成的SnsProfile , 还有一个其他Profiles , 这里我们不涉及Generic和Supporting Doman的规划 , 主要从业务核心Domain出发 。 一个同学用PPT阐述了划分结构和出发点 , 如下:
苏眠月|DDD as Code:如何用代码诠释领域驱动设计?但是也有同学说是不是UML的Component图更好一些 , 方便和后面的UML图统一 , 如下:
苏眠月|DDD as Code:如何用代码诠释领域驱动设计?当然还有其他如Visio等非常多的图示工具用于展现结构图 。 DDD的第一步:SubDomain的划分和展现 , 就有不同的理解方式 , 如何描述、如何图形化展现 , 都有不少的分歧 。
回到问题的出发点 , 我们就想划分一下SubDomain , 那么是不是下述的DSL代码也可以:
Domain User {domainVisionStatement = "User domain to manage account, tags, profiles and payment profile."Subdomain AccountDomain {type = CORE_DOMAINdomainVisionStatement = "Account domain to save sensitive data and authentication"}Subdomain UserTagDomain {type = GENERIC_SUBDOMAINdomainVisionStatement = "UserTag domain manage user's KV and Boolean tag"}Subdomain PaymentProfileDomain {type = CORE_DOMAINdomainVisionStatement = "User payment profile domain to manage credit/debit card, Alipay payment information"}Subdomain SnsProfileDomain {type = CORE_DOMAINdomainVisionStatement = "User Sns profile domain to manage user Sns profile for Weibo, Wechat, Facebook and Twitter."}Subdomain ProfilesDomain {type = CORE_DOMAINdomainVisionStatement = "User profiles domain to manage user basic profile, interest profile etc"}}虽然目前我们还不知道对应的DSL代码语法 , 但是我们已经知道Domain的名称、domain类型以及domain的愿景陈述(visionStatement) , 至于后期以何种方式展现系统Domain , 如表格、图形等 , 这个可以考虑基于现在的数据进行展现 。 其中的UserTagDomain类型为GENERIC_SUBDOMAIN , 这个表示打标是通用性Domain , 如我们后期可以和商品、图片或者视频团队合作 , 大家可以一起共建打标系统 。
注意:Subdomain不只是简单包括type和domainVisionStatement , 同时你可以添加Entity和Service , 其目的主要是突出核心特性并方便你对Domain的理解 , 如Account中添加resetPassword和authBySmsCode , 相信大多数人都知道这是什么含义 。 但是注意不要将其他对象添加到Subdomain , 如VO, Repository, Domain Event等 , 这些都是辅助开发的 , 应该用在BoundedContext中 。
Subdomain AccountDomain {type = CORE_DOMAINdomainVisionStatement = "Account domain to save sensitive data and authentication"Entity Account {long idString nickString mobileString ^emailString nameString saltString passwdint statusDate createdAtDate updatedAt}Service AccountService {void updatePassword(long accountId, String oldPassword, String newPassword);void resetPassword(long acountId);boolean authByEmail(String email, String password);boolean authBySmsCode(String mobile, String code);}}Context Map
ContextMap主要是描述各个Domain中各个BoundedContext间的关联关系 , 你可以理解为BoundedContext的拓扑地图 。 这里我们先不详细介绍BoundedContext , 你现在只需要理解为实现Domain的载体 , 如你编写的HSF服务应用、一个处理客户请求的Web应用或者手机App , 也可以是你租用的一个外部SaaS系统等 。 举一个例子 , 你的系统中有一个blog的SubDomain , 你可以自行开发 , 也可以架设一个WordPress , 或者用Medium实现Blog 。 回到微服务的场景 , 如何划分微服务应用?SubDomain对应的是业务或者虚拟的领域 , 而BoundedContext则是具体支持SubDomain的微服务应用 , 当然一个SubDomain可能对应多个微服务应用 。