原文連結:
http://jeoff.blog.51cto.com/186264/88517/POJO = pure old java object or plain ordinary java object or what ever.
PO = persisent object 持久對象
就是說在一些Object/Relation Mapping工具中,能夠做到維護資料庫表記錄的persisent object完全是一個符合Java Bean規範的純Java對象,沒有增加别的屬性和方法。全都是這樣子的:
private long id;
private String name;
public void setId(long id) {
this.id = id;
}
public void setName(String name) {
this.name=name;
public long getId() {
return id;
public String getName() {
return name;
}
---------------------------------------------------------------------------
首先要差別持久對象和POJO。
持久對象實際上必須對應資料庫中的entity,是以和POJO有所差別。比如說POJO是由new建立,由GC回收。但是持久對象是
insert資料庫建立,由資料庫delete删除的。基本上持久對象生命周期和資料庫密切相關。另外持久對象往往隻能存在一個資料庫
Connection之中,Connnection關閉以後,持久對象就不存在了,而POJO隻要不被GC回收,總是存在的。
由于存在諸多差别,是以持久對象PO(Persistent
Object)在代碼上肯定和POJO不同,起碼PO相對于POJO會增加一些用來管理資料庫entity狀态的屬性和方法。而ORM追求的目标就是要
PO在使用上盡量和POJO一緻,對于程式員來說,他們可以把PO當做POJO來用,而感覺不到PO的存在。
JDO的實作方法是這樣的:
1、編寫POJO
2、編譯POJO
3、使用JDO的一個專門工具,叫做Enhancer,一般是一個指令行程式,手工運作,或者在ant腳本裡面運作,對POJO的class檔案處理一下,把POJO替換成同名的PO。
4、在運作期運作的實際上是PO,而不是POJO。
該方法有點類似于JSP,JSP也是在編譯期被轉換成Servlet來運作的,在運作期實際上運作的是Servlet,而不是JSP。
Hibernate的實作方法比較先進:
3、直接運作,在運作期,由Hibernate的CGLIB動态把POJO轉換為PO。
由此可以看出Hibernate是在運作期把POJO的位元組碼轉換為PO的,而JDO是在編譯期轉換的。一般認為JDO的方式效率會稍高,畢竟
是編譯期轉換嘛。但是Hibernate的作者Gavin
King說CGLIB的效率非常之高,運作期的PO的位元組碼生成速度非常之快,效率損失幾乎可以忽略不計。
實際上運作期生成PO的好處非常大,這樣對于程式員來說,是無法接觸到PO的,PO對他們來說完全透明。可以更加自由的以POJO的概念操縱
PO。另外由于是運作期生成PO,是以可以支援增量編譯,增量調試。而JDO則無法做到這一點。實際上已經有很多人在抱怨JDO的編譯期Enhancer
問題了,而據說JBossDO将采用運作期生成PO位元組碼,而不采用編譯期生成PO位元組碼。
另外一個相關的問題是,不同的JDO産品的Enhancer生成的PO位元組碼可能會有所不同,可能會影響在JDO産品之間的可移植性,這一點有點類似EJB的可移植性難題。
-----------------------------------------------------------------------------------
由這個問題另外引出一個JDO的缺陷。
由于JDO的PO狀态管理方式,是以當你在程式裡面get/set的時候,實際上不是從PO的執行個體中取values,而是從JDO StateManager中取出來,是以一旦PM關閉,PO就不能進行存取了。
在JDO中,也可以通過一些辦法使得PO可以在PM外面使用,比如說定義PO是transient的,但是該PO在PM關閉後就沒有PO identity了。無法進行跨PM的狀态管理。
而Hibernate是從PO執行個體中取values的,是以即使Session關閉,也一樣可以get/set,可以進行跨Session的狀态管理。
在分多層的應用中,由于持久層和業務層和web層都是分開的,此時Hibernate的PO完全可以當做一個POJO來用,也就是當做一個
VO,在各層間自由傳遞,而不用去管Session是開還是關。如果你把這個POJO序列化的話,甚至可以用在分布式環境中。(不适合lazy
loading的情況)
但是JDO的PO在PM關閉後就不能再用了,是以必須在PM關閉前把PO拷貝一份VO,把VO傳遞給業務層和web層使用。在非分布式環境中,
也可以使用ThreadLocal模式確定PM始終是打開狀态,來避免每次必須進行PO到VO的拷貝操作。但是不管怎麼說,這總是權宜之計,不如
Hibernate的功能強。
PO:
persistant object持久對象
最形象的了解就是一個PO就是資料庫中的一條記錄。
好處是可以把一條記錄作為一個對象處理,可以友善的轉為其它對象。
--------------------------------------------------------------------------------
BO:
business object業務對象
主要作用是把業務邏輯封裝為一個對象。這個對象可以包括一個或多個其它的對象。
比如一個履歷,有教育經曆、工作經曆、社會關系等等。
我們可以把教育經曆對應一個PO,工作經曆對應一個PO,社會關系對應一個PO。
建立一個對應履歷的BO對象處理履歷,每個BO包含這些PO。
這樣處理業務邏輯時,我們就可以針對BO去處理。
VO :
value object值對象
ViewObject表現層對象
主要對應界面顯示的資料對象。對于一個WEB頁面,或者SWT、SWING的一個界面,用一個VO對象對應整個界面的值。
DTO :
Data Transfer Object資料傳輸對象
主要用于遠端調用等需要大量傳輸對象的地方。
比如我們一張表有100個字段,那麼對應的PO就有100個屬性。
但是我們界面上隻要顯示10個字段,
用戶端用WEB service來擷取資料,沒有必要把整個PO對象傳遞到用戶端,
這時我們就可以用隻有這10個屬性的DTO來傳遞結果到用戶端,這樣也不會暴露服務端表結構.到達用戶端以後,如果用這個對象來對應界面顯示,那此時它的身份就轉為VO
POJO :
plain ordinary java object 簡單java對象
個人感覺POJO是最常見最多變的對象,是一個中間對象,也是我們最常打交道的對象。
一個POJO持久化以後就是PO
直接用它傳遞、傳遞過程中就是DTO
直接用來對應表示層就是VO
DAO:
data access object資料通路對象
這個大家最熟悉,和上面幾個O差別最大,基本沒有互相轉化的可能性和必要.
主要用來封裝對資料庫的通路。通過它可以把POJO持久化為PO,用PO組裝出來VO、DTO
總結下我認為一個對象究竟是什麼O要看具體環境,在不同的層、不同的應用場合,對象的身份也不一樣,而且對象身份的轉化也是很自然的。就像你對老婆來說就
是老公,對父母來說就是子女。設計這些概念的初衷不是為了唬人而是為了更好的了解和處理各種邏輯,讓大家能更好的去用面向對象的方式處理問題.
大家千萬不要陷入過度設計,大可不必為了設計而設計一定要在代碼中區分各個對象。一句話技術是為應用服務的。
歡迎指正。
畫了個圖,感覺沒有完全表達出自己的意思。。。。。誰幫忙完善下,最好能展現各個O在MVC中的位置

作者:
Candyメ奶糖出處:
http://www.cnblogs.com/Candies/本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
博文來源廣泛,如原作者認為我侵犯知識産權,請盡快給我發郵件
[email protected]聯系,我将以第一時間删除相關内容。