DDD领域模型阅读思考

DDD领域模型阅读思考

序言:

一家之言的文章,对于此文的内容,是本人对此概念的理解,加以自身的总结,高度概括,所以越发抽象,对其他人可能没有参考意义

业务设计之前:

  1. 常见软件设计模式注重数据库和数据表模型,把表捋出来来以后,仿佛代码流程就出来了,但这个只是多个存储模型,存储数据的流程,这样是能完成存储数据的功能,但是是很底层的设计思路,思路固化以后,会容易写出面条串似的业务流程代码, 没有确定 领域边界,不是至顶向下,而是从底向上的思考,这样的代码容易无组织,只有一串串堆叠的业务代码配合。复用也不容易。

  2. 技术人员不要陷入项目刚开始,就纠结于技术细节实现的泥潭(只是从数据存储,数据表方面等谈),一些显而易见的矛盾处还是应该指出,但一般业务从业人员也不会那么业余,先从战略上面确定整体领域边界和主要的领域模型,大白话就是系统组成模块边界。

具体实施

  1. 确立领域边界后,每个领域边界业务,利用包名的隔离性来单独隔离业务代码。对外提供的特定接口api 也需要起特定api包。利用接口进行交互。然后需要配合多个领域业务边界的地方需要继承

  2. 领域对象对外调用主要提供者是 所谓的 聚合根(就是利用聚合的方式,聚合了 领域对象,entity对象, 领域值对象是为了方便传输值存在的,要简洁),然后领域对象 entity 不止是数据库表对象,可能是把几个表 orm对象聚合在一起的东西,拥有自己的边界,有自己的职责和方法。聚合根把各个 entity对象,值对象 聚合起来,接口逻辑聚拢起来,代码逻辑内聚。强调的是对方调用方能调用的应该只有聚合根对象。 这个领域根对象还得理解其与持久化数据交互逻辑.

  3. 隔离真正service 和 普通调用者直接 可以加一层, ACL(所谓的 anti-currupt-layer,防腐层), 防腐层意义是在 隔离真正提供service,做了一层代理模式,用来沟通外部 业务,或者说外部领域 和 内部领域的信息交换,防止交缠过多,产生含糊不清。

  4. 单体应用分拆module的话需要结合各个领域边界业务,组合起来对外提供 service 的包, 利用proxy api层,然后需要module proxy 进行api bean注入,这个是单体应用的比较麻烦的地方。如果是微服务 边界业务进行沟通,那直接就是走网络,或http 或rpc 框架来走通信了,也就是 上下文集成手段。

  5. 领域服务的边界,以电商为例, 商品边界, 订单边界, 促销边界, 这些边界对外提供出口的服务层,不提api接口层的东西了,就说真正领域边界对外提供出口,外部调用只能通过这些对外提供的服务来用,这些服务层,一般是通过 内部组合 存储层服务来进行?
    少了聚合根做逻辑的聚集,但是这样是最显而易见最好实施的一种方式,仅仅通过这种方式能很快地进行开发。 因为聚合根的聚合需要一定的状态维护,会显得比较难以编写和意识边界,可能不利于前期开发的速度。 但是为了后期做模块内部的功能代码复用,建议还是要把 单纯的每个
    表的 dao 层,做 概念上的组合,就是一个大块概念的方式组合 这些dao 层, 这样这个中间层,可能会显得略庞大,需要相关别的方式来分割内部代码。中间层要合理放置接口边界,中间层概念理解为聚合根,聚合根要各司其职,足够合理的划分尺度

理解细化加深

子话题 - 分布式环境下, 领域模型实践,以及通过命令模式进行消息传递

  1. 分布式环境,事务一致性问题,改为 最终一致性,而不是强一致性,在 ap和 cp 中 选了 ap, 通过幂等发送,临时消息表, 事务方式插入消息, 消息队列, 幂等处理消息方式,保证了最终一致性, 但是 定时扫临时消息表,可能会导致高水位的表记录,和表压力,可以通过监听数据库变化的方式做更好地处理,例如 利用 canal 特性
  2. 微服务的幂等和事务更多依赖于事件驱动,也就是设计一套 发送幂等, 依靠消息队列, 消费幂等的一套消费事务体系。

Q&A 环节

– 提出问题:

  1. 实体对象是什么?就是数据库表吗?
    我目前理解是,实体对象是对业务来说,整体划分出来一个实体,它应该具有的特性是

实体

当一个对象由其标识(而不是属性)区分时,这种对象称为实体(Entity)。

例:最简单的,公安系统的身份信息录入,对于人的模拟,即认为是实体,因为每个人是独一无的,且其具有唯一标识(如公安系统分发的身份证号码)。

可以看到数据表有些是多对一关系,有些属性表,不能叫做实体对象。

你可能感兴趣的:(设计模式)