寫文章的緣由是阿里JAVA開發(fā)手冊多處提到DO、BO染坯、DTO均芽、VO险耀、PO等概念吓歇;
內(nèi)容多引用于網(wǎng)絡(luò)帖子上的回答榛鼎,如下:
概念及理解
這些概念用于描述對象的類型召调;由于Java是面向?qū)ο蟮恼Z言浸卦;程序的世界就是各個對象之間的“交互”冰蘑;在交互的工程中會存在多個層次掖桦,每個層次中所擁有(關(guān)注)的內(nèi)容都是不一樣的冕香;
PO(Persistant Object) 持久對象
用于表示數(shù)據(jù)庫中的一條記錄映射成的 java 對象儒喊。PO 僅僅用于表示數(shù)據(jù)镣奋,沒有任何數(shù)據(jù)操作。通常遵守 Java Bean 的規(guī)范怀愧,擁有 getter/setter 方法侨颈。
可以理解是一個PO就是數(shù)據(jù)庫中的一條記錄余赢;可以理解某個事務(wù)依賴的原始數(shù)據(jù);好處是可以將一條記錄最為一個對象處理哈垢,可以方便轉(zhuǎn)化為其他對象
BO(Business Object) 業(yè)務(wù)對象
封裝對象妻柒、復(fù)雜對象,里面可能包含多個類
主要作用是把業(yè)務(wù)邏輯封裝為一個對象耘分。這個對象可以包括一個或多個其它的對象举塔。
用于表示一個業(yè)務(wù)對象。BO 包括了業(yè)務(wù)邏輯求泰,常常封裝了對 DAO央渣、RPC 等的調(diào)用,可以進(jìn)行 PO 與 VO/DTO 之間的轉(zhuǎn)換拜秧。BO 通常位于業(yè)務(wù)層痹屹,要區(qū)別于直接對外提供服務(wù)的服務(wù)層:BO 提供了基本業(yè)務(wù)單元的基本業(yè)務(wù)操作,在設(shè)計上屬于被服務(wù)層業(yè)務(wù)流程調(diào)用的對象枉氮,一個業(yè)務(wù)流程可能需要調(diào)用多個 BO 來完成志衍。
比如一個簡歷,有教育經(jīng)歷聊替、工作經(jīng)歷楼肪、社會關(guān)系等等。
我們可以把教育經(jīng)歷對應(yīng)一個PO惹悄,工作經(jīng)歷對應(yīng)一個PO春叫,社會關(guān)系對應(yīng)一個PO。
建立一個對應(yīng)簡歷的BO對象處理簡歷泣港,每個BO包含這些PO暂殖。
這樣處理業(yè)務(wù)邏輯時,我們就可以針對BO去處理当纱。
VO(Value Object) 表現(xiàn)對象
前端界面展示呛每;value object值對象;ViewObject表現(xiàn)層對象坡氯;主要對應(yīng)界面顯示的數(shù)據(jù)對象晨横。對于一個WEB頁面,或者SWT箫柳、SWING的一個界面手形,用一個VO對象對應(yīng)整個界面的值;對于Android而言即是activity或view中的數(shù)據(jù)元素悯恍。
用于表示一個與前端進(jìn)行交互的 java 對象库糠。有的朋友也許有疑問,這里可不可以使用 PO 傳遞數(shù)據(jù)坪稽?實(shí)際上曼玩,這里的 VO 只包含前端需要展示的數(shù)據(jù)即可鳞骤,對于前端不需要的數(shù)據(jù),比如數(shù)據(jù)創(chuàng)建和修改的時間等字段黍判,出于減少傳輸數(shù)據(jù)量大小和保護(hù)數(shù)據(jù)庫結(jié)構(gòu)不外泄的目的豫尽,不應(yīng)該在 VO 中體現(xiàn)出來。通常遵守 Java Bean 的規(guī)范顷帖,擁有 getter/setter 方法美旧。
DTO(Data Transfer Object) 數(shù)據(jù)傳輸對象
前端調(diào)用時傳輸;也可理解成“上層”調(diào)用時傳輸;
比如我們一張表有100個字段贬墩,那么對應(yīng)的PO就有100個屬性榴嗅。但是我們界面上只要顯示10個字段,客戶端用WEB service來獲取數(shù)據(jù)陶舞,沒有必要把整個PO對象傳遞到客戶端嗽测,這時我們就可以用只有這10個屬性的DTO來傳遞結(jié)果到客戶端,這樣也不會暴露服務(wù)端表結(jié)構(gòu).到達(dá)客戶端以后肿孵,如果用這個對象來對應(yīng)界面顯示唠粥,那此時它的身份就轉(zhuǎn)為VO.
用于表示一個數(shù)據(jù)傳輸對象。DTO 通常用于不同服務(wù)或服務(wù)不同分層之間的數(shù)據(jù)傳輸停做。DTO 與 VO 概念相似晤愧,并且通常情況下字段也基本一致。但 DTO 與 VO 又有一些不同蛉腌,這個不同主要是設(shè)計理念上的官份,比如 API 服務(wù)需要使用的 DTO 就可能與 VO 存在差異。通常遵守 Java Bean 的規(guī)范舅巷,擁有 getter/setter 方法
DAO(Data access object) 數(shù)據(jù)訪問對象
這個大家最熟悉,和上面幾個O區(qū)別最大悄谐,基本沒有互相轉(zhuǎn)化的可能性和必要.,主要用來封裝對數(shù)據(jù)庫的訪問。通過它可以把POJO持久化為PO们陆,用PO組裝出來VO寒瓦、DTO;
用于表示一個數(shù)據(jù)訪問對象坪仇。使用 DAO 訪問數(shù)據(jù)庫,包括插入椅文、更新惜颇、刪除、查詢等操作少辣,與 PO 一起使用凌摄。DAO 一般在持久層,完全封裝數(shù)據(jù)庫操作漓帅,對外暴露的方法使得上層應(yīng)用不需要關(guān)注數(shù)據(jù)庫相關(guān)的任何信息。
POJO(Plain ordinary java object) 簡單java對象
一個POJO持久化以后就是PO忙干;直接用它傳遞、傳遞過程中就是DTO捐迫;直接用來對應(yīng)表示層就是VO。
舉個例子:
事情:統(tǒng)計研發(fā)部門中的季度績效(暫定以工程師填寫的為準(zhǔn)反浓,當(dāng)然實(shí)際上大部分不是)
過程:CTO發(fā)布統(tǒng)計績效請求(附帶要求:每個人對應(yīng)的績效等級)->各個組(也可以是子部門)負(fù)責(zé)人發(fā)布統(tǒng)計績效請求(每個對應(yīng)的績效等級暇韧,并將績效分為了3個方面)->每位開發(fā)工程師統(tǒng)計自己績效(自身各個方面)勾习;
可以從例子中看到:每個責(zé)任人要求都不同懈玻;
對于CTO,他需要知道的是該季度所用員工的績效等級艺栈;這里可以認(rèn)為VO:員工姓名、績效等級湿右;
開發(fā)工程師:需將本人這個季度的各個方面的表現(xiàn)都列出來:員工姓名罚勾、績效等級、A方面表現(xiàn)內(nèi)容及等級尖殃、B方面表現(xiàn)內(nèi)容及等級、C方面表現(xiàn)內(nèi)容及等級送丰、D方面表現(xiàn)內(nèi)容及等級、E方面表現(xiàn)內(nèi)容及等級俐载、F方面表現(xiàn)內(nèi)容及等級、E方面表現(xiàn)內(nèi)容及等級遏佣;此處可認(rèn)為是PO:員工姓名、績效等級贼急、A方面表現(xiàn)內(nèi)容、A方面等級….E方面表現(xiàn)內(nèi)容太抓、E方面等級;
然后開發(fā)工程師將員工姓名碴倾、績效等級掉丽、A方面表現(xiàn)內(nèi)容及等級、B方面表現(xiàn)內(nèi)容及等級捶障、C方面表現(xiàn)內(nèi)容及等級內(nèi)容傳遞給小組負(fù)責(zé)人;此處傳遞的對象就是DTO
小組負(fù)責(zé)人:從開發(fā)工程師中獲取到數(shù)據(jù)后项炼,經(jīng)過評定,然后得出員工姓名暂论、績效等級拌禾、原因;此處的評定湃窍,可以理解為BO;