【DDD】领域驱动设计实践 —— 限界上下文识别
本文从战略层面街上DDD中关于限界上下文的相关知识,并以ECO系统为例子,介绍如何识别上下文。限界上下文(Bounded Context)定义了每个模型的应用范围,在每个Bounded Context中确保领域模型的一致性;上下文图(Context Map)表示各个系统之间关系的总体视图;通过持续集成(Continous Integration)确保多个限界上下文的模型统一。
限界上下文(Bounded Context)
限界上下文(Bounded Context)定义了每个模型的应用范围,在每个Bounded Context中确保领域模型的一致性。不同的限界上下文中,领域模型可以不用保证一致性。通常我们根据团队的组织、软件系统的每个部分的用法及物理表现(如组件划分,数据库模式)来设置模型的边界。
上下文图(Context Map)
多个系统之间会发生关系,存在交互,这也必然会在各自的Bounded Context上有所表现。上下文图(Context Map)便是表示各个系统之间关系的总体视图。在Context Map中可以有如下几种形式来表征限界上下文之间的关系,他们分别是:
共享内核(Shared Kernel)
当不同团队开发一些紧密相关的应用程序时,团队之间需要进行协调,通常可以将两个团队共享的子集剥离出来形成共享内核(Shared Kernel),双方进行持续集成(Continuous Integration)。由此可见共享内核(Shared Kernel)是业务领域中公共的部分,同时也是团队间容易达成且必须达成共识的领域部分。
客户/供应商(Customer/Supplier)
不同系统之间存在依赖关系时,下游系统依赖上游系统,下游系统是客户,上游系统是供应商,双方协定好需求,由上游系统完成模型的构建和开发,并交付给下游系统使用,之后进行联调、测试。这种模式建立在团队之间友好合作和支持的情况下。
Conformist(追随者)
如果上游系统不合作,这时候“客户/供应商”模式就不凑效了,那么下游系统只能去追随上游系统,下游系统严格遵从上游系统的模型,简化集成。
例如在ECO系统中,社区服务的打赏记录来源于支付系统,支付系统的打赏记录这一模型设计较为友好,且社区服务只是一个简单的查询模型,可以直接追随支付系统的打赏记录模型,集成简单快速。
防腐层(Anticorruption Layer)
如果上游系统的模型不友好,不适合下游系统的场景,但是下游系统又必须依赖于这些模型,这时候我们需要使用防腐层(Anticorruption Layer)模式将上游系统的影响降低。这种模式也是非常常见的,通常出现在系统间对接时,使用trasport+resolver的方式完成服务调用和协议转换。其中的resovler便承担了防腐的作用。
公开主机服务(Open Host Service)
公开主机服务(Open Host Service)能够允许系统将一组service公开出去公其他系统访问,在互通模型的同时,减少了系统间的耦合。
此类模式是使用最多的。系统之间的交互通常是使用该模式来完成的,而且现在很火的微服务架构也可以理解为此类模式的实现形式。
各行其道(Separate Way)
当两个系统之间的关系并非必不可少时,两者完全可以彼此独立,各自独立建模,独立发展,互不影响。
模式图谱

思考
综合上述模式,由上而下耦合越来越低,模型的共享程度也越来越低,在实践中,使用得最多的应当是:防腐层 + 公开主机服务的搭配使用。实际开发中,一个上游系统会面对多个下游系统做过多定制化的建模,且由于团队组织和管理上的天然隔离,团队合作的紧密度通常并不会那么高,因此,要做到“共享内核”和“客户/供应商”模式是比较困难的。我认为如今发展的如火如荼的微服务架构便是“防腐层 + 公开主机服务”的实现形式,使用RESTful契约公开主机服务,在业务模型上使用防腐层完成隔离和适配,达到共享模型和降低耦合的平衡。
“共享内核”模式在通用业务领域较为常见,在细分业务领域中,通常由几家厂商抽象出通用的业务模型,并产品化,售卖给各个甲方企业,在实施集成过程中,根据甲方的个性化诉求,在“共享内核”上做二次开发。比如在网上银行这一细分的业务领域中,大小银行的网银系统基本上被科蓝和宇信两家公司承包,且两家公司都已经产品化,具体项目实施时,只需要做一些二次开发,便可快速集成上线。
“客户/供应商”模式个人觉得实施起来会比较困难,毕竟是跨团队协作,及时领头上司是一个,如果这个关键人物不去把控系统设计,那么业务模型上的一致性是很难保证的,最后估计会演变为“防腐层”模式;如果这个关键人物会实际参与到系统建模和设计中,那实际上编程了一个大的团队了,也就无所谓“客户/供应商”模式了,都是自己了。
在ECO系统中的实践
结合上述理论知识,及实际实践,我们发现ECO系统中主要使用到了:“追随者”、“防腐层”、“公开主机服务”三种模式,他们的使用场景分别为:
- ECO直接使用支付系统的“打赏记录”模型作为其查询模型,使用到了“追随者”模式;
- ECO访问内容过滤服务,对内容过滤服务的访问模型进行了适配,这里使用到了“防腐层”模式;
- ECO系统通过RESTful服务提供内网服务供其他业务系统内网访问,比如积分系统获取用户的发帖/评论情况等,使用到了“公开主机服务”模式;
综上,我们可以画出ECO系统的Content Map,如下:

【DDD】领域驱动设计实践 —— 限界上下文识别的更多相关文章
- DDD领域驱动设计和实践(转载)
-->目录导航 一. DDD领域驱动设计介绍 1. 什么是领域驱动设计(DDD) 2. 领域驱动设计的特点 3. 如果不使用DDD? 4. 领域驱动设计的分层架构和构成要素 5. 事务脚本和领域 ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(3)
上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(2)> 这篇文章主要是对 DDD.Sample 框架增加 Transa ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(2)
上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(1)> 阅读目录: 抽离 IRepository 并改造 Reposi ...
- DDD领域驱动设计落地实践(十分钟看完,半小时落地)
一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)
好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...
- DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(转)
http://www.cnblogs.com/xishuai/p/ddd-repository-iunitofwork-and-idbcontext.html 好久没写 DDD 领域驱动设计相关的文章 ...
- 【DDD】领域驱动设计实践 —— UI层实现
前面几篇blog主要介绍了DDD落地架构及业务建模战术,后续几篇blog会在此基础上,讲解具体的架构实现,通过完整代码demo的形式,更好地将DDD的落地方案呈现出来.本文是架构实现讲解的第一篇,主要 ...
- 浅谈我对DDD领域驱动设计的理解
从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...
- DDD 领域驱动设计-商品建模之路
最近在做电商业务中,有关商品业务改版的一些东西,后端的架构设计采用现在很流行的微服务,有关微服务的简单概念: 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成.系统中的各个微服务可被独 ...
随机推荐
- RedHat Enterprise Linu…
RedHat Enterprise Linux 6.4 使用Centos 6 的yum 源问题 2015.04.09 一.问题描述 有时在使用RedHat 系统进行安装某些软件时,会出现如下提示: T ...
- Docker实践 - 安装Docker并在容器里运行tomcat
安装Docker yum install docker 本文使用的系统是centos7,ubuntu使用以下命令 sudo apt-get update sudo apt-get install do ...
- js prototype 继承
//继承 function inherits(ctor,superCtor){ ctor.super_ = superCtor; ctor.prototype = Object.create(supe ...
- Unity 坐标 转换 详解 World世界坐标 Screen屏幕坐标 View视口坐标 GUI坐标 NGUI坐标 localPosition相对父级坐标
在制作游戏中我们经常会遇到这样一个需求: 在人物模型的上面显示 名字.称号 一类的文字或者图片 如下图 人物模型属于是Camera1 UI Title信息属于NGUI Camera2 如下图 这时 ...
- JavaScript闭包只学这篇就够了
闭包不是魔法 这篇文章使用一些简单的代码例子来解释JavaScript闭包的概念,即使新手也可以轻松参透闭包的含义. 其实只要理解了核心概念,闭包并不是那么的难于理解.但是,网上充斥了太多学术性的文章 ...
- 案例:数据库open时报错ORA-1172,ORA-1151 处理
环境:OEL 5.7 + Oracle 10.2.0.5 Clusterware + Oracle 10.2.0.5 RAC 故障:数据库open时报错ORA-1172,ORA-1151 1.故障详细 ...
- Weex的原生开发
weex概念与特性 最形象的理解就是类似react native. Weex几大特点: 1.帮助你构建原生应用 与 Web App.HTML5 App 或 hybrid App 不同,您可以使用 We ...
- k近邻法(KNN)知识点概括
分类一般分为两种: 积极学习法:先根据训练集构造模型,然后根据模型对测试集分类 消极学习法:推迟建模,先简单存储训练集,等到给定测试集时再进行建模,如KNN算法. 1. 简述 KNN的核心思想就是:物 ...
- Android App 压力测试 monkeyrunner
Android App 压力测试 第一部分 背景 1. 为什么要开展压力测试? 2. 什么时候开展压力测试?第二部分 理论 1. 手工测试场景 2. 自动测试创建 3. Monkey工具 4. ADB ...
- node.js之require
1.require.resolve('./testModeule.js')在REPL运行环境下输入,可以查询到当前目录下textModeule.js模块文件的完整文件名 2.require.cache ...