項目領域模型的應用

1.領域對象的使用

用於項目不同層次間的數據交互,並可以在不同層次中實現轉換;

所有的領域對象建議使用貧血模型;

領域對象的使用會使得類數量增多;

2.常見的幾種領域對象

1.PO (persistant object)持久對象 / Entity:通常對應數據模型 ( 數據庫 )。可以看成是與數據庫中的表相映射的 Java 對象, PO 中應該不包含任何對數據庫的操作。

2.DO(Domain Object)領域對象:從現實世界中抽象出來的有形或無形的業務實體。大多數情況下是與PO一一對應的。但是它還可以表示多個PO之間的業務關係(與PO接近)。

3.DTO(Data Transfer Object)數據傳輸對象:泛指用於展示層(web和api層)與服務層(service)之間的數據傳輸對象。

4.VO(View Object):視圖對象,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來(使用統一返回對象Result<xxxDto>()代替)。

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  <interface>
領域對象 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 <interface>,與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);

ps: 領域對象轉換工具:mapstruct (實際使用存在部分字段轉換失敗的情況/bug,建議手動寫默認方法實現轉換,idea安裝GenerateAllSetter插件),或是淺拷貝 BeanUtils.copyProperties (缺點:1.對兩個轉換對象有要求,2.反射犧牲了性能)

實踐規約

1. 各個模塊層級之間,不能跨級引用,不能層級倒轉引用:即web -> api -> service -> service/manager -> dal;

2. 同層級只能單向引用不能循環引用,A service引用了B sevice,那麼B service不能引用A service;

3. Controller層統一獨立抽出放置網關中,所有的參數校驗放在網關層;

4. Service層只能注入DAO(不建議),Manager層的依賴;

5. po/entity不可在web層,api層中暴露,系統對外提供的領域對象爲dto;

6. 儘量每個請求使用不同的query;

7.dto需要實現序列化接口;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章