切換語言為:簡體
專案分層開發中,真的有必要定義 VO 嗎?

專案分層開發中,真的有必要定義 VO 嗎?

  • 爱糖宝
  • 2024-08-27
  • 2058
  • 0
  • 0

DTO、BO、PO、VO是什麼

在討論這些是什麼的時候,建議先看看這篇文章:

https://juejin.cn/post/7312357312445481012

在上面這篇文章中提到的缺乏模型抽象,無邊界控制,就是正好對應的DTO BO PO VO這些模型的概念

如何對模型進行抽象,控制邊界,可用看看這篇文章 :

https://juejin.cn/post/7333458486435987494

在後端開發中,比如傳統的MVC架構和現在流行的DDD架構,經常會使用到下列幾種物件的概念

  • DTO (Data Transfer Object) 數據傳輸物件: DTO設計模式用於將資料從服務端傳輸到客戶端,或者在不同的服務之間傳遞。通常,DTO包含了特定業務場景需要的數據結構,並且不包含任何業務邏輯。它簡化了不同服務或模組之間的互動,使得各個層之間的耦合度降低。

  • BO (Business Object) 業務物件: BO代表了業務邏輯層中的物件,封裝了與某個業務相關的資料以及針對這些資料的操作邏輯。一個BO可能由多個實體屬性組成,並處理涉及多個實體的複雜業務邏輯。

  • PO (Persistent Object) 持久化物件: PO主要用來表示資料庫表的一條記錄,它的屬性和資料庫表的欄位相對應。通常在持久層(如Hibernate、JPA等ORM框架)中使用,主要用於運算元據庫,如儲存、更新和查詢資料。

  • VO (Value Object) 值物件: VO是檢視層的物件,通常用於封裝展示給使用者的資料,它可以和資料庫表對應,也可以根據UI介面需求進行定製。VO的主要目的是在頁面展示時只攜帶必要的資料,從而避免把大量不必要的資料暴露給前端。

舉個實際程式碼的例子,這裏暫不給出VO,在最後的總結會講這個VO

  • 這個就是PO

@Data
public class User implements Serializable{
    private Long id;

    private String username;

    private String password;

    private String identityCard;

    private String gender;

    private String location;

    private String userImage;

    private String phoneNumber;

    private String createTime;

    private String updateTime;

    @TableLogic
    private int isDelete;
}

  • UserDTO

@Data
public class UserDTO implements Serializable{
    private Long id;

    private String username;

    private String password;

    private String identityCard;

    private String gender;

    private String location;

    private String userImage;

    private String phoneNumber;
}

  • UserLoginBO、UserUpdateBO ...

@Data
public class UserLoginBO implements Serializable{
    private String username;

    private String password;
}

@Data
public class UserUpdateBO implements Serializable{
    private Long id;

    private String username;

    private String password;

    private String identityCard;

    private String gender;

    private String location;

    private String userImage;

    private String phoneNumber;
}

從上面這個例子大家能看出來區別不

UserDTO是一個大的入口,它可以接收整個模組的引數

BO則是在進入Service層之前對UserDTO的資料進行過濾,並且對邊界進行控制

最後在進入infra層之前轉為PO

其實BO也可以像UserDTO那樣,直接一個UserBO包含UserLoginBO和UserUpdateBO,單純的做模型轉換,不做值過濾也可以

專案分層開發中,真的有必要定義 VO 嗎?

在後端開發中怎麼用的

專案分層開發中,真的有必要定義 VO 嗎?

總結

為什麼我們通篇沒有講關於VO的事情呢?

我個人的理解是DTO能解決的事情沒有必要再加一個VO,我們可以弄一個全域性配置,將DTO裡面為null值的欄位全都過濾掉

這樣就沒有說將資料傳給前端的時候需要加多一個VO

給出程式碼示例,這樣配置就可以把DTO中為null值過濾掉,不會序列化發給前端

@Configuration
public class GlobalConfig extends WebMvcConfigurationSupport {

    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(mappingJackson2HttpMessageConverter());
    }
    /**
     * 自定義mappingJackson2HttpMessageConverter
     * 目前實現:空值忽略,空欄位可返回
     */
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return new MappingJackson2HttpMessageConverter(objectMapper);
    }
}

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.