• Geek_45ddff
    2019-12-30
    希望把完整样例代码放出来

    作者回复: 这两天会加一篇完整的代码详解。

     2
     2
  • ANYI
    2019-11-15
    1,对于实体采用充血模型,包含自己的属性及行为,例如保持、更新、删除等行为方法,需要持久化,依赖基础层数据库操作,是在实体直接引入,例如mybatis的mapper?
    2,对于相对简单的实体操作增删改查这种,需要暴露到接口层;那要一层一层向上封装,实体》领域服务》应用服务》接口服务;这样是不是又显得代码很多余;一个简单的增加修改方法接口,需要很多冗余代码,上层也没有其他逻辑,封装一下调用下层,写一个接口,要写很多层次调用,是否会很臃肿啰嗦,是不是就可以直接接口层封装就省去一些层呢?
    3,在服务编排上有没有一些框架什么的?还是都是通过if else的手写?

    作者回复: 1、实体的这些数据库映射是通过mapper来实现的。
    2、松散分层架构是可以跨层调用了,实现起来很容易。但是在复杂的情况下,服务不太容易管理,比如,你可能不知道你的方法到底被谁组合和封装了,一旦出现方法变更,你不容易一次找出所有受影响方。而逐层封装的话,你只需要逐层通知到上层就可以了。
    3、微服务内的服务编排相对简单,就是业务逻辑的执行顺序而已,个人感觉不需要引入什么工具。

     6
     2
  • 何沛
    2019-11-15
    abcAppService{
          abDomainService();
          c.f();//老师这里是不是应该调整为cDomainService();
    }

    作者回复: 谢谢指出,图已调整。

    
     1
  • 张迪
    2019-11-15
    领域实体的方法必须要通过领域服务封装一下吗?

    作者回复: 如果直接对外暴露的话,建议封装一下。避免业务逻辑泄露。

    
     1
  • AlexHuang
    2019-11-15
    老师讲的很好!
    请教一个问题,聚合根下的方法(比如:创建个人客户信息)和领域服务中的方法(比如:创建个人客户信息)功能会不会重叠,对外暴露的场景是什么?

    作者回复: 实体的功能实现是在聚合根,其它服务只是封装和编排,服务内部不实现实体的业务逻辑,所以不会出现功能重叠的情况。有些前端可能不需要服务组合和编排,直接调用创建客户的方法,这就是跨层暴露,所以建议封装一下后,再暴露。

    
     1
  • 盲僧
    2019-11-15
    作者代码的地址可以发一下吗,或者给个demo

    作者回复: 等我有时间的时候,我整理一个吧。

    
     1
  • 吴海洋
    2019-11-15
    写得不错,通俗易懂。文章结构也符合我的阅读习惯。👍
    
     1
  • 鸭子
    2019-11-15
    领域服务过多会不会导致领域中的实体对象对象变成贫血模型,如果没有领域服务又很可能把领域内的逻辑放到应用服务用去,纠结。

    作者回复: 实体对象的方法在实体类内实现,有些领域服务只是做封装或者组合编排。
    领域逻辑别放到应用服务中去,容易让领域模型逻辑与编排逻辑出现混乱,最后做成三层架构了。

    
     1
  • 赵宇浩
    2020-02-10
    问题一:
    假如用户是个复杂聚合根,同时存在List的操作一般怎么处理。
    比如支持单用户信息创建以及批量用户信息创建。
    单用户的实体创建包含基本信息校验和仓储写入两个步骤。
    但批量创建不太可能循环调用每个用户的创建方法吧。

    所以这样就要给用户这个类再加个基本信息校验的方法?
    然后领域服务层,循环校验之后,再批量写入?

    但这样用户这个类,就要有两个构造方法?
    一个需要持有仓储(单用户操作),
    一个不需要持有仓储(用于多用户操作)?

    问题二:
    比如用户里包含了地址和账户。
    那么仓储的事务怎么考虑,事务也由用户这个类去保证么?还是事务在领域服务里实现?
    实现一:在用户实体里持有用户仓储,账户实体里持有账户仓储,然后用户创建的方法里,先调用账户的写入方法,再调用自己的仓储保存,如果自己存储失败,回滚?听上去好像可以实现,也符合逻辑。但是感觉这个类的每次实例初始化是不是有点麻烦。
    实现二:实体不持有仓储,领域服务是单例的,就可以直接注入用户,账户,地址的仓储,然后只是组装内存数据,在领域服务层依次调用仓储,保证事务。也可以实现,但这样实体的责任是不是太弱了,这个领域服务层和三层架构的service层是不是有点像。

    不知道实际中怎么做更推荐,望指导
    展开
     1
    
  • okjesse
    2020-02-05
    【如果一个业务动作或行为跨多个实体,我们就需要设计领域服务】,请问这个实体指的是一个聚合根下面的多个实体吗。 我看例子代码也是一个聚合根会有一个领域服务,会存在一个领域服务跨多个聚合根吗。
    
    
  • 小美
    2020-01-29
    想问下实体的增删改查是由实体来做还是领域服务来做?谁来调用仓储

    作者回复: 实体自身的方法来完成增删改,复杂查询可以交由应用服务来做。仓储接口可以在应用服务或者领域服务中调用,也可以是聚合根的方法里。

    
    
  • 山巅最小的费马质数颗...
    2020-01-03
    老师,如果存储是在实体类里面调用repository,那么我们要通过spring注入这些repository,但是实体理论上是每次new出来的新对象,那么我们就不能直接用@component啥的了,因为默认是单例的,这样我们岂不是每次创建实体都得自己调用applicationcotext.getbean来得到prototype的实体,或者把这个封装成工厂,所有创建实体都走工厂?

    作者回复: 复杂聚合用工厂来实现吧。

    
    
  • ZIxuAN
    2019-12-25
    老师,领域层调用仓储添加实体,是在实体里面调用还是在领域服务中调用。实体中会涉及持久化操作吗

    作者回复: 通过工厂来完成所有关联实体的初始化。一般都在领域服务里面来调工厂和仓储完成持久化。

    
    
  • okjesse
    2019-12-23
    请问你们repository使用的是jpa还是mybatis,有使用mybatis-plus吗。最好能有个代码模板。

    作者回复: 两个都可以的。后面的微服务样例我用的是JPA,过一段时间后我会发给大家的。

     1
    
  • 胡杨
    2019-12-12
    DDD里的领域事件可以用类似nopcommerce框架里的继承注册监听的方式来简单实现么?

    作者回复: 不好意思啊,没有接触过nopcommerce相关的的组件。微服务之间的领域事件大多还是通过消息中间件的模式。你说的注册和监听是不是指的微服务内部事件总线的功能,如果能实现领域事件的发布和监听,能实现不同聚合之间的解耦,我觉得应该是可以用的。

    
    
  • @倾杯
    2019-12-09
    老师,代码模型这块我还有一点不太确定,就是dto->do这个转换方法具体是在controller中调用还是在xxAppService中调用呢?反过来do->dto方法又该是在哪个类里调用呢?

    作者回复: 你可以在用户接口层创建DTO类和assembler类。在assembler类里完成映射。

    
    
  • 鱼养猫
    2019-12-06
    服务A调用服务B,是放在基础设施层吗?

    作者回复: 你说的是微服务之间的服务调用,还是微服务内的应用服务或领域服务?微服务之间服务调用可以通过API网关来调用,API网关是基础层的组件。微服务内的服务调用,直接服务跨层调用就可以了。

    
    
  • 鱼养猫
    2019-12-06
    数据的持久化是在领域服务中还是实体中?如果持久化放在实体中,使用spring和mybatis就得把实体声明@Component 注入mapper,还得设置多例.持久化是否可以放在领域服务中去做?

    作者回复: 持久化是通过仓储来做。这样通过依赖倒置,可以解耦领域模型实现与数据库资源。

    
    
  • Geek_4660f3
    2019-12-01
    1、领域服务和聚合根是什么关系
    2、领域服务是封装了多个实体的业务,那么领域服务是存放在聚合根内的么
    3、应用服务是直接调用领域服务还是调用聚合根

    作者回复: 聚合根由于管理了聚合内所有的实体和值对象,它的有些方法其实可以替代部分领域服务的功能。但是我建议聚合根本身的业务行为放在聚合根的方法内,聚合内的所有领域服务用一个单独的领域服务类来实现。
    应用服务应该调用领域服务。

    
    
  • Jesen
    2019-11-29
    老师,如果把仓储Respository的实现放到基础设施层,其仓储接口定义在领域层里面,那么在领域层里面该怎么持久化呢,可以通过在应用层中将仓储注入到领域服务里面来实现吗?

    作者回复: 这个只是代码存放目录的考虑。具体的持久化是在仓储实现的服务里面。为了方便聚合的重新组合,我在代码目录结构里面将仓储的接口和实现都放在领域层的聚合目录下,如果微服务架构演进,你可以直接将聚合相关的代码一起拿走。

    
    
我们在线,来聊聊吧