Advertisement

项目领域模型的应用

阅读量:

1.领域对象的使用

用于项目不同层次间的数据交互,并可以在不同层次中实现转换;

所有的领域对象建议使用贫血模型;

领域对象的使用会使得类数量增多;

2.常见的几种领域对象

PO(Persistent Object)持久对象 / Entity一般相当于对应着数据模型(数据库)。其中一种可以看成是Java对象,并且与数据库中的表相映射;同时,在PO中不应该包含任何对数据库的操作。

DO(Domain Object)领域对象:通过提炼现实世界中的核心要素而形成的实体或虚拟概念,在大多数情况下它能够与特定的Product Object(PO)实现一一对应的关系。然而,在某些复杂场景下,一个DO可能会代表多个PO之间的交互关系(如业务流程中的关联性)。

3.DTO(Data Transfer Object)作为数据传输实体,在展示及API层与服务端之间扮演着重要角色。

在Web开发中, VO(View Object)代表显示层对象.它位于展示层中,并负责将特定页面或组件的所有数据整合到一个统一返回对象Result()中.

5.QUERY: 查询对象,用于数据访问层。

常用的有:po/entity, dto, query

3.项目分层

(摘自阿里开发规范)

4.各层的领域对象

5.项目分包结构

web, api, service, dal

复制代码
 +---zhku-dal

    
 |   +---src\main\java\com\zhku\computer
    
 |   |   |                           +---entity
    
 |   |   |                           +---po
    
 |   |   |                           +---manager
    
 |   |   |                           +---mapper
    
 |   |   |                           +---config
    
 |   |   |                           +---enum
    
 |   |   |                           /---resource
    
 |   |   |                              +---xml
    
 +---zhku-service
    
 |   +---src\main\java\com\zhku\computer
    
 |   |   |                           +---impl
    
 |   |   |                           +---remote
    
 |   |   |                           +---convert
    
 |   |   |                           +---util
    
 +---zhku-service-api
    
 |   +---src\main\java\com\zhku\computer
    
 |   |   |                       \---api
    
 |   |   |                           +---service
    
 |   |   |                           +---query
    
 |   |   |                           +---dto
    
 |   |   |                           +---exception
    
 \---zhku-web
    
   |   +---src\main\java\com\zhku\computer
    
     |   |   |                   \---web
    
     |   |   |                       +---config
    
     |   |   |                       +---api
    
     |   |   |                       +---route
    
     |   |   |                       +---mobile
    
    
    
    
    代码解读
web层 UserController
领域对象 query, dto
复制代码
 @PostMapping(value = "/v1/school/{userId}")

    
 public ZHKUResult<UserDto> saveUser(@Validated UserSaveQuery query) {
    
      userService.saveUser(query);
    
      return new ZHKUResult<>();
    
 }
    
  
    
 @DeleteMapping(value = "/v1/school/{userId}")
    
 public ZHKUResult removeUser(@Validated UserQuery query) {
    
      userService.removeUser(query);
    
      return new ZHKUResult();
    
 }
    
  
    
 @PutMapping(value = "/v1/school/{userId}")
    
 public ZHKUResult<UserDto> updateUser(@Validated UserSaveQuery query) {
    
      userService.updateUser(query);
    
      return new ZHKUResult();
    
 }
    
  
    
 @GetMapping(value = "/v1/school/{userId}")
    
 public ZHKUResult<UserDto> findUser(@Validated UserQuery query) {
    
      return new ZHKUResult<UserDto>(userService.findUser(query));
    
 }
    
  
    
    
    
    
    代码解读
service-api层 UserService
领域对象 query, dto
复制代码
 void saveUser(UserSaveQuery query);

    
  
    
 void removeUser(UserQuery query)
    
  
    
 void updateUser(UserSaveQuery query)
    
  
    
 UserDto findUser(UserQuery query)
    
    
    
    
    代码解读
service层 UserServiceImpl
领域对象 query, dto, po/entity
复制代码
 void saveUser(UserSaveQuery query){

    
     systemService.validated(query);  //other service api, exp: dubbo api / http api
    
     UserEntity user = convert.toUserEntity(query);
    
     userManager.saveUser(user);
    
 }
    
  
    
 void deleteUser(UserQuery query){
    
     String userId = query.getUserId();
    
     userManager.deleteUser(userId);
    
 }
    
  
    
 void updateUser(usersaveQuery query){
    
     UserEntity user = convert.toUserEntity(query);
    
     userManager.updateUser(user);
    
 }
    
  
    
 UserDto findUser(UserQuery query){
    
     String userId = query.getUserId();
    
     UserEntity user = userManager.findUser(userId);
    
     return convert.toUserDto(user);
    
 }
    
    
    
    
    代码解读
dal-manager层 userManager
领域对象 po/entity
复制代码
 void saveUser(UserEntity user){

    
     userMapper.saveUser(user);
    
 }
    
  
    
 void deleteUser(String userId){
    
     userMapper.deleteUser(userId);
    
 }
    
  
    
 void updateUser(UserEntity user){
    
     userMapper.updateUser(user);
    
 }
    
  
    
 UserEntity findUser(String userId){
    
     return userMapper.findUser(userId);
    
 }
    
    
    
    
    代码解读
dal层 UserMapper ,与xml绑定
领域对象 po/entity
复制代码
 void saveUser(@Param("user") UserEntity user);

    
  
    
 void deleteUser(@Param("userId") String userId);
    
  
    
 void updateUser(@Param("user")UserEntity user);
    
  
    
 UserEntity findUser(@Param("userId")String userId);
    
    
    
    
    代码解读

域外对象转码工具:MapStruct(在实际应用中遇到部分字段无法完成转码的问题,请手动编写默认方法以解决转码问题,并安装IDEA中的GenerateAllSetter插件),或者采用ShallowCopyBeanUtils.copyProperties(该方法有两个主要限制条件:一是对两个要进行转码的对象有要求;二是从性能上受到了影响)

实践规约

各模块之间的层级结构中不允许出现跨层次或逆向的引用关系;例如:web layer → API layer → service layer → service/manager layer → DAL;

在同层级之间只能进行单向引用而禁止循环引用。例如,在服务架构中,A服务已经调用了B服务,因此B服务就不能再调用A服务

3. Controller层统一独立抽出放置网关中,所有的参数校验放在网关层;

4. Service层只能注入DAO(不建议),Manager层的依赖;

5. po/entity不可在web层,api层中暴露,系统对外提供的领域对象为dto;

6. 尽量每个请求使用不同的query;

7.dto需要实现序列化接口;

全部评论 (0)

还没有任何评论哟~