分层架构之模型,DO,DTO之间的关系

按照一个请求实体进入系统后,它在分层架构的各层之间传递的顺序,可以分为,请求命令层,领域模型层,业务实现层。那么各层实体如何创建?存在的形态?各层级之间实体的传递方式是什么样的呢?

请求命令层

这一层如果进行了CQRS命令改造,那么命令可以分为读请求Query,写请求Command,事件请求(写命令)Event。这一层的价值在于传递命令或请求,不做任何其他的事情,是纯的pojo,有get/set方法。

如创建用户命令:

public class CreateUserCmd {
  private String name;
  private Integer phone;
  
  // get/set 方法
}

请求命令层的实体定义在COLA框架中client层。client层的价值在于能够为客户端(web,wap,作为jar包)提供各种现成的纯实体,方便客户端调用。

请求命令层的实例产生于adaptor层,即对应到web请求,或者消息实体,adaptor层依赖于client层,然后在adaptor层传递到app层。整个过程我们不会主动调用请求命令的set方法,它的价值在于传递客户端的信息,预留set方法主要是为了满足框架的实体转换需求。

领域模型层

领域模型层是所有业务逻辑实现的地方,每个模型要包含其所有的逻辑操作。抛开逻辑实现,我们只关注领域模型实体如何生成。

  1. 构造函数

最基本的方式是我们给领域实体暴露出的构造函数。

比如

public class User implement Entity {
   private String name;
   private Integer phone;
   public User(String name, Integer phone) {
     this.name = name;
     this.phone = phone;
   }
  
   public void initDefaultPermission() {
     // 初始化用户权限
   }
}

请求从adaptor层进入app层再到领域层,这时我们借助请求命令里的信息,如name,phone字段,去创建我们的领域模型实例new User(name.phone),再用创建出的user去执行业务方法user.initDefaultPermission()

  1. 领域工厂

对于复杂的模型,可以用工厂方法来构建。

  1. 构建者

对于业务字段多,字段之间有约束的实体,用构建者模式会更加方便。

注意,领域实体没有set方法。它的一切实例化都要用它暴露出去的方法,要么是构造方法,要么是工厂方法,绝对不可以用new对象,然后set的方式,以免造成模型一致性的破坏。

业务实现层

纯POJO,主要用作持久化层或RPC之间的传递数据的作用。

从领域实体到它的转化,主要靠set方法。

UserDO userDo = new UserDO();
userDO.setName(name);
userDO.setPhone(phone);

可以用mapstruct等工具简化这个过程。当然有的领域实体和实现层之间的字段也会有差异,比如领域层定义的是enum,而实现层的DO是一个String,这种就需要手动转化一下。主要写一写胶水语句,没有实现上的难度。

而从业务实现层到领域实体的转化,靠领域实体的构造器,工厂或构建者,也就是上面说过的三种方式。

总结

其实除了领域层的领域实体要用领域暴露的方法来构建,其他的都是纯POJO。主要目的是为了保证领域模型的逻辑一致性。不要破坏这种规则。

原文地址:https://www.cnblogs.com/SimonZ/p/15734622.html