PO,BO,VO,DTO,POJO,DAO,Entity,JavaBean,JavaBeans的區分(附圖文)

PO (Persistent Object)

PO((bean,entity等命名):持久化對象,它跟持久層(通常是關係型數據庫)的數據結構形成一一對應的映射關係。
如果持久層是關係型數據庫,那麼,數據表中的每個字段(或若干個)就對應PO的一個(或若干個)屬性。

VO(value object) 值對象 (view object)視圖對象

VO(View Object):視圖對象,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。
主要體現在視圖的對象,對於一個WEB頁面將整個頁面的屬性封裝成一個對象。然後用一個VO對象在控制層與視圖層進行傳輸交換。
我們可以這樣理解:
即 用戶填寫當前頁面信息之後,把這些頁面信息與VO對象對應起來,傳到service層進行業務處理。

BO(business object) 業務對象

從業務模型的角度看 , 見 UML 元件領域模型中的領域對象。封裝業務邏輯的 java 對象 , 通過調用 DAO 方法 , 結合 PO,VO 進行業務操作。 business object: 業務對象 主要作用是把業務邏輯封裝爲一個對象。這個對象可以包括一個或多個其它的對象。 比如一個簡歷,有教育經歷、工作經歷、社會關係等等。 我們可以把教育經歷對應一個 PO ,工作經歷對應一個 PO ,社會關係對應一個 PO 。 建立一個對應簡歷的 BO 對象處理簡歷,每個 BO 包含這些 PO 。 這樣處理業務邏輯時,我們就可以針對 BO 去處理。

DO (Domain Object):領域對象,就是從現實世界中抽象出來的有形或無形的業務實體。

DTO(Data Transfer Object):數據傳輸對象

DTO:數據傳輸對象(Data Transfer Object)
是一種設計模式之間傳輸數據的軟件應用系統,數據傳輸目標往往是數據訪問對象從數據庫中檢索數據
數據傳輸對象與數據交互對象或數據訪問對象之間的差異是一個以不具任何行爲除了存儲和檢索的數據(訪問和存取器)
簡而言之,就是接口之間傳遞的數據封裝
表裏面有十幾個字段:id,name,gender(M/F),age……
頁面需要展示三個字段:name,gender(男/女),age
DTO由此產生,一是能提高數據傳輸的速度(減少了傳輸字段),二能隱藏後端表結構
在這裏插入圖片描述
ACTION:指的是控制層即Contoller

JavaBean 一種可重用組件

即“一次性編寫,任何地方執行,任何地方重用”。滿足三個條件①類必須是具體的和公共的②具有無參構造器③提供一致性設計模式的公共方法將內部域暴露成員屬性。

主要用途:可以用在 功能、處理、值、數據庫訪問和JSP中任何可以用Java代碼創造的對象。

有兩種:一種是有用戶界面(UI,User Interface)的JavaBean;還有一種是沒有用戶界面,主要負責處理事務(如數據運算,操縱數據庫)的JavaBean。JSP通常訪問的是後一種JavaBean。

分類:通常有Session bean,Entity bean,MessageDrivenBean三大類

——Session bean會話構件,是短暫的對象,運行在服務器上,並執行一些應用邏輯處理,它由客戶端應用程序建立,其數據需要自己來管理。分爲無狀態和有狀態兩種。
——Entity bean實體構件,是持久對象,可以被其他對象調用。在建立時指定一個唯一標示的標識,並允許客戶程序,根據實體bean標識來定位beans實例。多個實體可以併發訪問實體bean,事務間的協調由容器來完成。
——MessageDriven Bean消息構件,是專門用來處理JMS(Java Message System)消息的規範(EIB2.0)。JMS是一種與廠商無關的API,用來訪問消息收發系統,並提供了與廠商無關的訪問方法,以此來訪問消息收發服務。JMS客戶機可以用來發送消息而不必等待迴應。

JavaBean

JavaBeans:JavaBeans 從狹義來說,指的是 JavaBeans 規範也就是位於 java.beans 包中的一組 API。從廣義上來說,JavaBeans 指的是 API 集合,比如 Enterprise JavaBeans。

POJO(Plain Ordinary Java Object)簡單的Java對象

實際就是普通JavaBeans,是爲了避免和EJB混淆所創造的簡稱。通指沒有使用Entity Beans的普通java對象,可以把POJO作爲支持業務邏輯的協助類。

POJO實質上可以理解爲簡單的實體類,顧名思義POJO類的作用是方便程序員使用數據庫中的數據表,對於廣大的程序員,可以很方便的將POJO類當做對象來進行使用,當然也是可以方便的調用其get,set方法。POJO類也給我們在struts框架中的配置帶來了很大的方便。
一個POJO持久化以後就是PO
直接用它傳遞、傳遞過程中就是DTO
直接用來對應表示層就是VO

在這裏插入圖片描述

########################################################################

VO,DTO,DO,PO的聯繫以及區別

在這裏插入圖片描述

  • 用戶發出請求(可能是填寫表單),表單的數據在展示層被匹配爲VO。

  • 展示層把VO轉換爲服務層對應方法所要求的DTO,傳送給服務層。

  • 服務層首先根據DTO的數據構造(或重建)一個DO,調用DO的業務方法完成具體業務。

  • 服務層把DO轉換爲持久層對應的PO(可以使用ORM工具,也可以不用),調用持久層的持久化方法,把PO傳遞給它,完成持久化操作。

  • 對於一個逆向操作,如讀取數據,也是用類似的方式轉換和傳遞,略。

舉例理解

下面重點說下這幾個,他們都是POJOPO 持久對象,數據;
BO 業務對象,封裝對象、複雜對象 ,裏面可能包含多個類;
DTO 傳輸對象,前端調用時傳輸 ;
VO 表現對象,前端界面展示。

當你業務足夠簡單時,一個POJO 也完全當做PO BO DTO VO 看,下面是例子:比如有個用戶類 只有 name 以及 phone 對於數據庫層面也就兩列,業務層面,傳輸,和前臺展示時 都只有這兩項。

然後說下他們區別開來的例子:
1 、還是用戶類 name phone 加了個password。那麼你後端的PO屬性也是這3個,一般數據庫裏這個表有幾個字段你的PO就有多少屬性,但是傳輸到前臺或者展現時,我們不應該把password 密碼這種東西也一起傳過去,所以他們的DTO VO 就還是 name + phone
po : name phone password
dto : name phone
vo : name phone

2、現在又加了一個 枚舉的狀態位 status 表示用戶的一些特殊狀態,前臺不會直接顯示,可能會根據這個狀態產生後續的操作,
po : name phone password status
dto : name phone status
vo : name phone

3、接着看下BO ,一個用戶下面 肯定會關聯很多其他的表比如用戶設置 用戶信息等,那麼這個BO 下 不但有用戶本身的一些屬性,還包含了用戶設置 和用戶信息這兩個類。

VO和DTO的區別

大家可能會有個疑問:既然DTO是展示層與服務層之間傳遞數據的對象,爲什麼還需要一個VO呢?對!對於絕大部分的應用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,因此沒必要多此一舉,但不要忘記這是實現層面的思維,對於設計層面來說,概念上還是應該存在VO和DTO,因爲兩者有着本質的區別,DTO代表服務層需要接收的數據和返回的數據,而VO代表展示層需要顯示的數據。

用一個例子來說明可能會比較容易理解:例如服務層有一個getUser的方法返回一個系統用戶,其中有一個屬性是gender(性別),對於服務層來說,它只從語義上定義:1-男性,2-女性,0-未指定,而對於展示層來說,它可能需要用“帥哥”代表男性,用“美女”代表女性,用“祕密”代表未指定。說到這裏,可能你還會反駁,在服務層直接就返回“帥哥美女”不就行了嗎?對於大部分應用來說,這不是問題,但設想一下,如果需求允許客戶可以定製風格,而不同風格對於“性別”的表現方式不一樣,又或者這個服務同時供多個客戶端使用(不同門戶),而不同的客戶端對於表現層的要求有所不同,那麼,問題就來了。再者,回到設計層面上分析,從職責單一原則來看,服務層只負責業務,與具體的表現形式無關,因此,它返回的DTO,不應該出現與表現形式的耦合。

理論歸理論,這到底還是分析設計層面的思維,是否在實現層面必須這樣做呢?一刀切的做法往往會得不償失,下面我馬上會分析應用中如何做出正確的選擇。

DTO和DO的區別

首先是概念上的區別,DTO是展示層和服務層之間的數據傳輸對象(可以認爲是兩者之間的協議),而DO是對現實世界各種業務角色的抽象,這就引出了兩者在數據上的區別,例如UserInfo和User(對於DTO和DO的命名規則,請參見筆者前面的一篇博文),對於一個getUser方法來說,本質上它永遠不應該返回用戶的密碼,因此UserInfo至少比User少一個password的數據。而在領域驅動設計中,DO不是簡單的POJO,它具有領域業務邏輯。

DO與PO的區別

DO和PO在絕大部分情況下是一一對應的,PO是隻含有get/set方法的POJO,但某些場景還是能反映出兩者在概念上存在本質的區別:

  • DO在某些場景下不需要進行顯式的持久化,例如利用策略模式設計的商品折扣策略,會衍生出折扣策略的接口和不同折扣策略實現類,這些折扣策略實現類可以算是DO,但它們只駐留在靜態內存,不需要持久化到持久層,因此,這類DO是不存在對應的PO的。

  • 同樣的道理,某些場景下,PO也沒有對應的DO,例如老師Teacher和學生Student存在多對多的關係,在關係數據庫中,這種關係需要表現爲一箇中間表,也就對應有一個TeacherAndStudentPO的PO,但這個PO在業務領域沒有任何現實的意義,它完全不能與任何DO對應上。這裏要特別聲明,並不是所有多對多關係都沒有業務含義,這跟具體業務場景有關,例如:兩個PO之間的關係會影響具體業務,並且這種關係存在多種類型,那麼這種多對多關係也應該表現爲一個DO,又如:“角色”與“資源”之間存在多對多關係,而這種關係很明顯會表現爲一個DO——“權限”。

  • 某些情況下,爲了某種持久化策略或者性能的考慮,一個PO可能對應多個DO,反之亦然。例如客戶Customer有其聯繫信息Contacts,這裏是兩個一對一關係的DO,但可能出於性能的考慮(極端情況,權作舉例),爲了減少數據庫的連接查詢操作,把Customer和Contacts兩個DO數據合併到一張數據表中。反過來,如果一本圖書Book,有一個屬性是封面cover,但該屬性是一副圖片的二進制數據,而某些查詢操作不希望把cover一併加載,從而減輕磁盤IO開銷,同時假設ORM框架不支持屬性級別的延遲加載,那麼就需要考慮把cover獨立到一張數據表中去,這樣就形成一個DO對應對個PO的情況。

  • PO的某些屬性值對於DO沒有任何意義,這些屬性值可能是爲了解決某些持久化策略而存在的數據,例如爲了實現“樂觀鎖”,PO存在一個version的屬性,這個version對於DO來說是沒有任何業務意義的,它不應該在DO中存在。同理,DO中也可能存在不需要持久化的屬性。

通過以下這些文件查看總結:
https://www.zhihu.com/question/39651928
https://www.cnblogs.com/lyjin/p/6389349.html
https://www.hollischuang.com/archives/553
http://www.blogjava.net/johnnylzb/archive/2010/05/27/321968.html

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