Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

讨论一下,按照cola架构撸的重复代码太多 #271

Closed
lslvxy opened this issue Mar 17, 2022 · 5 comments
Closed

讨论一下,按照cola架构撸的重复代码太多 #271

lslvxy opened this issue Mar 17, 2022 · 5 comments

Comments

@lslvxy
Copy link

lslvxy commented Mar 17, 2022

比如我一个User模块
要写一个UserDO,UserDomain,UserCO,CreateUserCmd,UpdateUserCmd
这些POJO类的内容基本都是一致的,
求教下如何才能写的简洁一点

@shiyindaxiaojie
Copy link

每个对象的职责不一样。COLA 只是融入六边形架构 + CQRS + DDD 等架构思想的整合体,对于面向数据编程的开发模式,COLA 不适用,直接用阿里巴巴规范定义的那套分层架构来做更合适。

UserDO:数据库表,假设 user 表存了 userid、username、userpwd
UserDomain:实体,可能多个实体最多映射到的是一张表
UserCO:新版本是 UserDTO,数据传输对象,提供给外部调用的 API,如果用 UserDO 代替,不能把 userpwd 暴露出去吧
CreateUserCmd:假设是自增主键,id 就没有意义了
UpdateUserCmd:通过 id 更新实体,每个指令最好对应一种请求

官方给的例子确实太简单了,也有些地方写的不好。

@lslvxy
Copy link
Author

lslvxy commented Mar 21, 2022

@shiyindaxiaojie 基本上能理解,还有一点CreateUserCmd跟UserDTO的关系,我看实例里面是包含的关系,那么前端调用就要多包装一层感觉不太好的,
如果只copy字段的话确实是有很多重复的
我理解的app接受参数还是用DTO,然后在client层的api使用的是cmd,app层调用的时候把dto转成cmd这样是否可行

@shiyindaxiaojie
Copy link

我个人的理解是 CreateUserCmd(Command)、UserDTO、UserListByPageQry(Query) 都属于数据传输对象(DTO),更倾向网络协议的数据交换,Command 和 Query 是 CQRS 设计思想的实际应用。CreateUserCmd 包含 UserDTO 感觉是作者偷懒直接包含进来了哈,以实际场景为例,我们实际上是把 client 层定义的 API 暴露给 Web端开发人员、客户端开发人员、第三方服务调用这类外部接入,CreateUserCmd 和 UpdateUserCmd 直接把 UserDTO 带进来会有语义的问题,CreateUserCmd 可能不需要传 Id,UpdateUserCmd 需要传 Id 用来定位数据实体做更新操作,往复杂的讲,一个 UserDTO 根本没法覆盖每个 CRUD 操作的场景。实际上,我的做法是 CreateUserCmd、UpdateUserCmd 单独写字段,不包含 UserDTO,在做接口设计的时候按实际的需求来,然后通过 Assembler 组装器(可以利用 Mapstructs 映射,减少工作量)转化为 Entity 实体。

@shiyindaxiaojie
Copy link

UserDTO 我的设计是根据 UserByIdQry 单个对象查询、UserListByPageQry 分页查询返回的对象

新增用户场景:

public class UserAddCmd implements Serializable {

  private String userName;
  
  private String password;
}

修改用户场景:

public class UserModifyCmd implements Serializable {

  private Long userId; // 用户ID主键

  private String userName;
}

删除用户场景:

public class UserRemoveCmd implements Serializable {

  private Long userId;
}

Command 转换为实体的操作(App 层的 assembler 包):

@Mapper(componentModel = "spring",
	nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
	nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface UserAssembler extends DTOAssembler<UserDTO, User> {

  User toEntity(UserAddCmd cmd);

  User toEntity(UserModifyCmd cmd);
  
  User toEntity(UserRemoveCmd cmd);
}

@lslvxy
Copy link
Author

lslvxy commented Mar 28, 2022

非常感谢,深受启发

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants