前言

战术设计

战略设计为我们提供一种高层视野来审视我们的软件系统,主要包括领域/子域、通用语言、限界上下文和架构风格等概念,

而战术设计则将战略设计进行具体化和细节化,它主要关注的是技术层面的实施,也是对程序员来得最实在的地方。

战术设计的目的是保证战略的实现。在DDD中,代码就是设计本身,你不再需要那些繁文缛节的并且永远也无法得到实时更新的设计文档。

警惕贫血对象,要创建行为饱满的领域对象并不难,我们需要转变一下思维,将领域对象当做是服务的提供方,而不是数据容器,多思考一个领域对象能够提供哪些行为,而不是数据。

实体

一个实体模型就是一个独立的事物,采用充血模型,具有业务属性和业务行为。每个实体都拥有一个唯一的标识符,可以将它的个性化和所有其他类型相同或者不同的实体区分开。许多时候,实体是可变的,它的状态会随着时间发生变化。

对一个实体进行多次修改,修改后的数据和原来可能会不大相同,但它们依然是同一个实体,因为唯一标识没变。

值对象

一个值对象,是对一个不变的概念整体所建立的模型,没有一个唯一的标识符。在这个模型中,值就真的只有一个值。和实体不一样,它没有唯一标识符,而是由值类型封装的属性对比来决定相等性。此外,一个值对象不是实物,而是常常用来描述、量化或者测量一个实体。

一个典型的值对象是地址值对象,比如下单中,有下单人、商品信息、优惠信息、还有收货地址信息,如果地址信息用省、市、区等属性表示,会有些零碎,拿出来构成一个“地址”属性,会更合适一些,这个多个值的集合就是值对象了。

聚合

在DDD中,实体和值对象是很基础的领域对象,实体跟值对象都只是个体化的对象,它们的行为表现出来的是个体能力。聚合用来确保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性。

聚合是由业务和逻辑紧密关联的实体和值对象组合而成的。聚合是数据修改和持久化的基本单元。

聚合设计的四条基本规则

  • 在聚合边界内保护业务规则不变性
  • 聚合要设计得小巧
  • 只能通过标识符引用其他聚合
  • 使用最终一致性更新其他聚合

聚合根

每个聚合都有一个根实体,叫做聚合根,外界只能通过聚合根跟聚合通信。聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间数据不一致的问题。

如果把聚合比作一个团队,那么聚合根就是团队的leader,其他团队的需求都需要跟该团队的leader商量后才能开始动工。

领域服务

当某个操作不适合放在聚合和值对象上时,最好的方式便是使用领域服务了。

可以使用领域服务的地方,过度使用领域服务将导致贫血领域模型。

  • 执行一个显著的业务操作过程
  • 对领域对象进行转换
  • 已多个领域对象作为输入进行计算,结果产生一个值对象

领域服务不需要定义接口,直接定义实现即可

  • 如果接口有不同的实现,那么需要考虑领域中是否存在特定的功能行为
  • 如果我们采用了依赖注入或者工厂,即便接口和实现类是合并在一起的,我们依然能达到这样的目的。依赖倒置容器(例如 Spring)将完成服务实例的注入工作,由于客户端并不负责服务的实例化,它并不知道接口和实现类是分开的还是合并在一起的。

领域服务与实体方法的区别

  • 实体方法完成单一实体自身的业务逻辑,相对简单的原子业务逻辑
  • 领域服务则是多个实体组合出的相对服务的业务逻辑

仓储

仓储用于保存和获取聚合对象,应该将仓储看作一个对象的集合,而不是数据库的CRUD,更不是一张表一个仓储。

需要做到让用户无感知的,以为就在内存中使用一个集合一样。

仓储的出现就是为了让大家聚焦领域模型,不要聚焦表结构。

领域事件

领域事件是一条记录,记录着在限界上下文中发生的对业务产生重要影响的事情,经常用于保证两个聚合之间的一致性。

对于领域事件的命名,必须体现出模型的通用语言,这些名词是连接模型之间的桥梁,对发生的事情进行充分的沟通至关重要。

领域事件类型名称应该是对过去发生事情的陈述,即动词的过去式,如OrderCreated。

参考资料

  • 《领域驱动设计——软件核心复杂性应对之道》
  • 《实现领域驱动设计》
  • 《领域驱动设计精粹》

DDD(领域驱动设计)--战术设计的更多相关文章

  1. DDD 领域驱动设计-商品建模之路

    最近在做电商业务中,有关商品业务改版的一些东西,后端的架构设计采用现在很流行的微服务,有关微服务的简单概念: 微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成.系统中的各个微服务可被独 ...

  2. DDD领域驱动设计落地实践(十分钟看完,半小时落地)

    一.引子 不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野.该思想源于2003年 Eric Evans编写的"Domain-Driven Design领域驱动设计"简称DDD ...

  3. 浅谈我对DDD领域驱动设计的理解

    从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...

  4. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(3)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(2)> 这篇文章主要是对 DDD.Sample 框架增加 Transa ...

  5. DDD 领域驱动设计-两个实体的碰撞火花

    上一篇:<DDD 领域驱动设计-领域模型中的用户设计?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sample(代码已更新) 在 ...

  6. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(2)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(1)> 阅读目录: 抽离 IRepository 并改造 Reposi ...

  7. DDD 领域驱动设计-领域模型中的用户设计

    上一篇:<DDD 领域驱动设计-如何控制业务流程?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sample(代码已更新,并增加了 ...

  8. DDD 领域驱动设计-如何控制业务流程?

    上一篇:<DDD 领域驱动设计-如何完善 Domain Model(领域模型)?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sa ...

  9. DDD 领域驱动设计-如何完善 Domain Model(领域模型)?

    上一篇:<DDD 领域驱动设计-如何 DDD?> 开源地址:https://github.com/yuezhongxin/CNBlogs.Apply.Sample(代码已更新) 阅读目录: ...

  10. DDD领域驱动设计之领域服务

    1.DDD领域驱动设计实践篇之如何提取模型 2.DDD领域驱动设计之聚合.实体.值对象 3.DDD领域驱动设计之领域基础设施层 什么是领域服务,DDD书中是说,有些类或者方法,放实体A也不好,放实体B ...

随机推荐

  1. Dorado download注意事项

    uploader/uploader-SNAPSHOT uploader/uploader-RELEASE .....使用需要注意!

  2. 从直播商城系统的KOL效应分析,直播带货井喷的必然性

    网红营销.直播带货作为近年来的热点发展迅猛,同时也捧红了一个概念:KOL.随着直播商城系统的不断完善发展,让KOL成为近年来营销最热门的香饽饽.随着原创直播平台低门槛化.模板化内容创作和大数据智能分发 ...

  3. day86:luffy:前端发送请求生成订单&结算页面优惠劵的实现

    目录 1.前端发送请求生成订单 1.前端点击支付按钮生成订单 2.结算成功之后应该清除结算页面的数据 3.后端计算结算页面总原价格和总的真实价格并存到数据库订单表中 2.优惠劵 1.准备工作 2.前端 ...

  4. 基于C++语言实现机动车违章处罚管理系统

    这篇文章主要介绍了基于C++语言实现机动车违章处罚管理系统的相关资料,需要的朋友可以参考下 关键代码如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

  5. linux c语言 哲学家进餐---信号量PV方法一

    1.实验原理   由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题.该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的 ...

  6. Spring源码之注解的原理

    https://blog.csdn.net/qq_28802119/article/details/83573950 https://www.zhihu.com/question/318439660/ ...

  7. sql sever 2008基础知识

    下面是一些总结,如果执行时发现错误,可以查看错误消息进行解决,也可上网查资料 数据库的组成: 主数据文件:有且只有一个,扩展名为.mdf. 次数据文件:可以没有,也可以有任意个.扩展名为.ndf. 日 ...

  8. arm-linux校时和时钟同步

    # 将时间写到系统 date 2020.08.25-14:02:00 # 将时间同步到硬件时钟芯片 hwclock -f /dev/rtc1 -w # 将时间从硬件时钟芯片同步到系统 hwclock ...

  9. IAR_STM32_BootLoader

    1.STM32 Bootloader与APP IROM中可以分成两个区域,起始代码运行地址为0x08000000,这是基本固定的,可以将IROM的0x08000000 ~ 0x08002000这8KB ...

  10. CSRF和XSS的区别

    XSS是啥? xss就是跨域脚本攻击 什么是跨域脚本攻击? 就是在正常的输入框中(如:用户名修改等)插入script恶意代码,从而在你遍历数据的时候加载该js文件, 获取你的cookie或sessio ...