【簡略知識】項目開發中,VO,BO,PO,DO,DTO究竟是何方妖怪?

前言

在項目開發中,是否需要定義VO(視圖對象),BO(業務對象),PO(持久化對象),DO(領域對象),DTO(數據傳輸對象)取決于項目的規模、復雜性、團隊的協作方式以及項目的長遠規劃。

對于小型或者簡單的項目,如果團隊成員較少,項目需求穩定且迭代速度不是很快,確實可以不嚴格區分這些對象,使用簡單的POJO(Plain Old Java Object)來進行各層之間的數據傳遞。這樣做可以減少項目的復雜度,加快開發進度。

然而,對于大型或復雜的項目,尤其是那些需要長期迭代和維護的,以及參與人員較多的項目,定義這些不同的對象有其必要性:

  1. VO(視圖對象):它們用于前端展示,可以屏蔽后端數據結構的變化對前端的影響,有助于保持前后端的分離和松耦合。
  2. DTO(數據傳輸對象):在服務層和展示層之間傳輸數據時使用,它們可以減少網絡傳輸的數據量,提高性能,并且可以在不同層次之間提供一個清晰的界限。
  3. BO(業務對象):封裝了業務邏輯,可以提高代碼的復用性,使得業務邏輯更加清晰,易于維護。
  4. PO(持久化對象):它們與數據庫結構直接對應,有助于實現數據訪問層的封裝,降低持久化邏輯與業務邏輯的耦合。
  5. DO(領域對象):它們代表業務領域的概念,有助于構建領域模型,促進開發人員與業務專家之間的溝通。

易混點一:VO和DTO

首先VO是最常用的,但對于這個概念,網上也是眾說紛紜,value object 或 view object,一般說視圖對象或者值對象,我更傾向理解為視圖對象。說白了它就是展示用的,不管展示方式是網頁,還是客戶端,還是APP,只要是這個東西是讓人看到的,我們就把它封裝為VO。

VO比較容易混淆的是DTO,DTO是展示層與服務層之間傳遞數據的對象,可以這樣說,對于絕大部分的應用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,那么既然有了VO,為什么還需要DTO呢?

我們舉例來說明一下:

某公司有一個后臺服務,服務層有一個getUser的方法返回一個系統用戶,包含sex(性別)、年齡。對于服務層來說,DTO只從語義上定義,可能是這樣的:

{"gender":"男","age":35
}

但這個服務同時供多個客戶端使用(不同門戶),而不同的客戶端對于表現層的要求有所不同,比如管理端要求顯示準確的年齡,而應用端為了保護客戶隱私,只需要顯示一個年齡段即可。

管理端VO:

{"gender":"男","age":35
}

應用端VO:

{"gender":"男","age":30~40
}

從這個例子可以看出,DTO很有存在的必要,根據職責單一原則,服務層只負責業務,與具體的表現形式無關,DTO不應該出現與表現形式的耦合,DTO定義的是原始數據,VO再對DTO數據進行解釋。這下VO和DTO用法就清晰很多了。

職責單一原則(Single Responsibility Principle, SRP)是面向對象設計中的一個重要原則,由Robert C. Martin提出。該原則指出,任何一個軟件單元(如類、模塊或服務)都應當有且只有一個引起其變化的原因。這個原則的核心理念是提高代碼的內聚性,降低耦合性,使代碼更易于理解和維護。

易混點二:BO和PO

PO是持久對象,這個很好理解,就是實體和數據庫字段的對應,一個PO的數據結構對應著庫中表的結構,表中的一條記錄就是一個PO屬性,大多數情況下,PO僅僅作為PO只是用來增刪改使用。

PO比較容易混淆的是BO,BO是業務對象,對應的是某個具體的業務塊,可以包含多個屬性、對象。簡單點來說,我們可以把BO看作是PO的組合。

我們舉例來說明一下:

PO-1是交易記錄對象,PO-2是登錄記錄對象,PO-3是商品瀏覽記錄對象,PO-4是添加購物車記錄對象,PO-5是搜索記錄對象,BO是個人網站行為對象,BO對象:{PO-1;PO-2;PO-3;PO-4;PO-5}。這樣做的優點不言而喻,維護代碼的時候查看BO,就能知道這塊邏輯涉及多少表(PO)。

易混點三:BO和DTO

搞清楚了BO和PO各自的用途后,我們會發現BO和DTO有重疊功能,一樣可以對PO進行排列組合,那BO的存在的意義是什么呢?

從用途上進行根本的區別,BO是業務對象,DTO是數據傳輸對象,雖然BO也可以排列組合數據,但它的功能是對內的,比如上個例子中的BO對象包括{PO-1;PO-2;PO-3;PO-4;PO-5}還有其他字段屬性,但在提供對外接口時,BO對象中的某些屬性對象可能用不到或者不方便對外暴露,那么此時DTO只需要在BO的基礎上,抽取自己需要的數據,然后對外提供。

在這個關系上,通常不會有數據內容的變化,內容變化要么在BO內部業務計算的時候完成,要么在解釋VO的時候完成。

DO

DO是領域對象,就是從現實世界中抽象出來的有形或無形的業務實體。事實上,DO和PO在絕大部分情況下是一一對應的。阿里巴巴的開發手冊中的定義DO等同于PO,即與數據庫表結構一一對應,通過DAO層向上傳輸數據源對象。

上一張圖,更加直觀的展示這些名詞使用的節點:

在這里插入圖片描述

總結

VO,BO,PO,DTO這樣分層還是很有意義的。尤其在團隊成員較多的情況下,結構更加一目了然,同時也能很大程度避免多端系統數據所需不一致時,有人修改屬性影響其他頁面。但也完全沒有必要教條主義,把這些全部用上,需要根據所開發的業務復雜度來取舍,如果本身業務邏輯不負責,照搬全上反而讓開發變的更復雜。

例如業務不復雜,根本沒有多端展示的差異化,VO可以直接拿掉,直接使用DTO傳輸到前端數據即可。

同時在使用過程中,最重要的是要在團隊中達成共識,概念一致,如果使用了這些,但各按各的理解來,甚至抓起來就直接用,反而會讓代碼變得更亂,還不如直接POJO、DTO打天下。

另附這些概念命名規范:

  • 數據對象:xxxPO,xxx即為數據表名。(也可DO)
  • 數據傳輸對象:xxxDTO,xxx為業務領域相關的名稱。
  • 展示對象:xxxVO,xxx一般為網頁名稱。
  • 業務對象:xxxBO,xxx是業務名稱。

本文參考自Java知音。1


  1. https://mp.weixin.qq.com/s/3-wA3hh75pgoTJu0Rz3SXw ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715593.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715593.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715593.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CKKS EXPLAINED, PART 3: ENCRYPTION AND DECRYPTION

CKKS EXPLAINED, PART 3: ENCRYPTION AND DECRYPTION Introduction 在之前的文章中,CKKS解釋了第二部分:完整的編碼和解碼,我們看到了如何實現CKKS的編碼器和解碼器,這使我們能夠將向量轉換為多項式,反之亦然。這一步…

笨辦法學 Python3 第五版(預覽)(三)

原文:Learn Python the Hard Way, 5th Edition (Early Release) 譯者:飛龍 協議:CC BY-NC-SA 4.0 練習 30:假如 這是你將要輸入的下一個 Python 腳本,它向你介紹了if語句。輸入這個代碼,確保它能夠完美運行…

怎么快速編輯視頻

背景:怎么簡單快速編輯視頻 利用FFmpeg功能,簡單快速編輯視頻,如按9:16提前剪切視頻、替換背景音樂。 下載FFmpeg:https://ffmpeg.org/download.html 將FFmpeg的路徑添加到環境變量中: Windows:在系統的環…

Home-credit海外貸款信貸產品源碼/線上貸款產品大全/貸款平臺軟件源碼/海外借貸平臺

測試環境:Linux系統CentOS7.6、寶塔、PHP7.3、MySQL5.6,根目錄public,偽靜態laravel5,開啟ssl證書 語言:中文簡體、英文 laravel框架的程序有點多,這個團隊估計主要就是搞laravel開發的,基本上…

前端架構: 腳手架通用框架封裝之腳手架注冊和命令注冊開發(教程二)

腳手架注冊和命令注冊 1 )腳手架的注冊 接上文,仍舊在 abc-cli 項目中參考:https://blog.csdn.net/Tyro_java/article/details/136381086之前初始化的時候,使用的是 yargs, 現在我們想要使用 commander在cli包中安裝 commander $…

2024 最新版 Compose material3 下拉刷新

2024 最新版 Compose material3 下拉刷新,版本 > 1.2.0 的 compose material3 已經更新了下拉刷新組件的 Api 見 https://developer.android.com/jetpack/androidx/releases/compose-material3?hlzh-cn#1.2.0 使用方法:https://developer.android.…

YOLOv9獨家原創改進|增加SPD-Conv無卷積步長或池化:用于低分辨率圖像和小物體的新 CNN 模塊

專欄介紹:YOLOv9改進系列 | 包含深度學習最新創新,主力高效漲點!!! 一、文章摘要 卷積神經網絡(CNNs)在計算即使覺任務中如圖像分類和目標檢測等取得了顯著的成功。然而,當圖像分辨率較低或物體較小時&…

可以用來測試的接口

實際開發過程中,我們可以通過postman工具來測試接口 get請求 https://api.github.com/events?id1&nameuser post請求 http://httpbin.org/post 參數1:key1value1 參數2:key2value2

(C語言)回調函數

回調函數是什么? 回調函數就是?個通過函數指針調?的函數。 如果你把函數的指針(地址)作為參數傳遞給另?個函數,當這個指針被?來調?其所指向的函數 時,被調?的函數就是回調函數。回調函數不是由該函數的實現?…

技術閱讀周刊第十四期:常用的 Git 配置

技術閱讀周刊,每周更新。 歷史更新 20231122:第十一期20231129:第十二期20240105:第十三期:一些提高生產力的終端命令20240112:第十四期:Golang 作者 Rob Pike 在 GopherConAU 上的分享 How I w…

探索Manticore Search:開源全文搜索引擎的強大功能

在當今信息爆炸的時代,數據的快速檢索變得至關重要。無論是在電子商務網站、新聞門戶還是企業內部文檔,高效的搜索引擎都是確保用戶滿意度和工作效率的關鍵因素之一。而在搜索引擎領域,Manticore Search 作為一款開源的全文搜索引擎&#xff…

大模型(LLM)的量化技術Quantization原理學習

在自然語言處理領域,大型語言模型(LLM)在自然語言處理領域的應用越來越廣泛。然而,隨著模型規模的增大,計算和存儲資源的需求也急劇增加。為了降低計算和存儲開銷,同時保持模型的性能,LLM大模型…

2024最新算法:鸚鵡優化算法(Parrot optimizer,PO)求解23個基準函數(提供MATLAB代碼)

一、鸚鵡優化算法 鸚鵡優化算法(Parrot optimizer,PO)由Junbo Lian等人于2024年提出的一種高效的元啟發式算法,該算法從馴養的鸚鵡中觀察到的覓食、停留、交流和對陌生人行為的恐懼中汲取靈感。這些行為被封裝在四個不同的公式中…

c語言--qsort函數(詳解)

目錄 一、定義二、用qsort函數排序整型數據三、用qsort排序結構數據四、qsort函數的模擬實現 一、定義 二、用qsort函數排序整型數據 #include<stdio.h> scanf_S(int *arr,int sz) {for (int i 0; i < sz; i){scanf("%d", &arr[i]);} } int int_cmp(c…

消息隊列kafka

消息隊列解決的問題 1. 解耦&#xff0c;通過消息隊列實現應用之間解耦&#xff0c;模塊兒之間解耦 2. 跨線程/進程通信&#xff0c;通過消息隊列傳遞數據&#xff0c;實現不同線程/進程間通信 3. 提升系統穩定性&#xff0c;在高并發場景通過消息隊列緩沖&#xff0c;可以實…

哈啰Java 春招 24屆

時長 1h 3. 為什么使用分布式ID&#xff0c;解決了什么問題 4. Leaf算法了解嗎&#xff1f;講一下原理和工作流程以及優缺點 5. 有沒有可能導致id重復&#xff1f;該如何解決&#xff1f; 6. 項目中redis是如何運用的&#xff1f; 7. 項目中分布式鎖是如何實現的&#xff1f; 8…

解決在 Mac 上安裝 Adobe 軟件彈出提示:安裝包已經被損壞并且不能被打開。

問題&#xff1a; “INSTALLER” is damaged and can’t be opened. You should eject the disk image. 解決方法和步驟&#xff1a; 打開安裝包&#xff1b;將安裝包 “INSTALLER” 拖動復制到某個文件夾&#xff0c;復制后的文件路徑例如像這樣&#xff1a;/Users/michael…

LLC諧振變換器變頻移相混合控制MATLAB仿真

微?關注“電氣仔推送”獲得資料&#xff08;專享優惠&#xff09; 基本控制原理 為了實現變換器較小的電壓增益&#xff0c;同時又有較 高的效率&#xff0c;文中在變頻控制的基礎上加入移相控制&#xff0c; 在這種控制策略下&#xff0c;變換器通過調節一次側開關管 的開關…

leetcode 熱題 100_盛最多水的容器

題解一&#xff1a; 雙指針遍歷&#xff1a;容量計算公式為min(左高度&#xff0c;右高度)*底部距離&#xff0c;我們可以令底部距離逐步遞減&#xff08;左右兩邊的指針向中部移動&#xff09;。此時對于min(左高度&#xff0c;右高度)&#xff0c;假設較高的線向中部移動&…

帶你玩轉數據結構-單鏈表(適合初學者的文章,講解的很仔細哦)

前言: &#x1f388;個人主頁:&#x1f388; :???初階牛??? &#x1f43b;推薦專欄: &#x1f354;&#x1f35f;&#x1f32f; C語言進階 &#x1f511;個人信條: &#x1f335;知行合一 &#x1f349;本篇簡介:>:講解數據結構中鏈表的知識,;鏈表的分類,c語言實現單鏈…