一个很形象的隐喻:细胞质所以能够存在,是因为细胞膜限定了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜(引用);
与技术组件保持一致将限界上下文想象成技术组件是可以的,但是技术组件并 不能来定义(是说不能定义概念?) 限界上下文,有几种做法:
在使用 IntelliJ IDEA 时,一个 限界上下文 通常就是一个工程项目;
在使用Java时,顶层包名通常表示 限界上下文中顶层模块 的名字;
一个团队,一个限界上下文(即便项目按分层架构模块划分,团队依然应该只工作在一个限界上下文中);
上下文映射图确定了单个限界上下文之后,有时还需要确定多个限界上下文之间的关系,这时就需要上下文映射图
一个项目的 上下文映射图 可以用两种方式来表示:
画一个简单的框图来表示 两个或多个 限界上下文 之间的 映射关系(该框图表示了不同的限界上下文在 解决方案空间 中是如何通过集成相互关联的);
通过 限界上下文 集成的源代码实现来表示;
限界上下文界分和集成康威定律 告诉我们,系统结构 应尽量与 组织结构 保持一致
这里认为团队结构(无论是内部组织还是团队间组织)就是 组织结构,限界上下文 就是 系统结构;
因此,团队结构 应该和 限界上下文 保持一致。
梳理清楚上下文之间的关系,从 团队内部 的关系来看,有如下好处:
任务更好拆分(一个开发人员可以全身心的投入到相关的一个单独的上下文中);
沟通更加顺畅(一个上下文可以明确自己对其他上下文的依赖关系,从而使得团队内开发直接更好的对接);
从 团队间 的关系来看,明确的上下文关系能够带来如下帮助:
每个团队在它的限界上下文中能够更加明确自己领域内的概念(因为限界上下文是领域的 解决方案空间);
对于限界上下文之间发生交互,团队与限界上下文的一致性,能够保证我们明确对接的团队和依赖的上下游;
限界上下文之间的映射关系
合作关系(Partnership):两个限界上下文建立起来的一种 紧密合作关系,要么一起成功,要么一起失败;
共享内核(Shared Kernel):两个限界上下文紧密依赖共享的 部分模型和代码;
客户方-供应方开发(Customer-Supplier Development):两个限界上下文有计划的 产生相互依赖(当两个团队处于上下游关系时,下游团队开发会受到上游开发的影响,上游团队计划应该估计下游团队的需求);
遵奉者(Conformist):下游限界上下文只能 盲目依赖 上游限界上下文的现象;
防腐层(Anticorruption Layer):一个限界上下文通过转换和翻译与其他的限界上下文进行交互;
开放主机服务(Open Host Service):定义一种协议,让其他限界上下文通过该协议对本限界上下文进行访问;
发布语言(Published Language):两个限界上下文之间翻译模型所需要的公用语言,通常与开放主机服务一起使用;
另谋他路(Separate Way):两个限界上下文之间不存在任何关系,寻找另外更简单、更专业的方法来解决问题;
大泥球(Big Ball of Mud):混杂在一起的、边界非常模糊的限界上下文关系;
领域/上下文划分的原则在划分的过程中,经常纠结的一个问题是:这个模型(概念或数据)看起来放这个领域合适,放另一个也合适,如何抉择 呢?
依据该模型与边界内其他模型或角色 关系的紧密程度(比如,是否当该模型变化时,其他模型也需要进行变化;该数据是否通常由当前上下文中的角色在当前活动范围内使用);
服务边界内的 业务能力职责应单一,不是完成同一业务能力的模型不放在同一个上下文中;
划分的子域和服务需满足 正交原则(模块的独立性,领域名字代表的自然语言上下文保持互相独立);
组织中 业务部分的划分 也是一种参考(组织架构,一个业务部门的存在往往有其独特的业务价值);
简单打个比方,同一个领域上下文中的模型要保持 近亲关系,五福以内,同一血统(业务)。
DDD之战术 实体当一个对象由其 唯一的身份标志 区分、具有可变的特性,这种对象即为实体。
实体属性的验证可以放在实体内部进行
值对象将领域概念建模成 值对象 的时候,应该将通用语言考虑在内,这是前提。(为什么将通用语言考虑在内?值对象 是领域里的一个概念,大家要统一认知,用通用语言作为标准,可以达到共同理解的目的)
构建值对象,要了解 值对象 以下的特点:
它度量或者描述了 领域中的一件东西;
它可以作为 不变量;
它将不同的相关的属性组合成一个 概念整体;
当度量和概念改变时,可以用另一个值对象予以 替换;
它可以和其他值对象进行相等性 比较;
它不会对协作对象造成任何副作用;