前言:
在Java開發中經常遇到這些概念問題,有的可能理解混淆,有的可能理解不到位,特此花了很多時間理順了這些概念。不過有些概念實際開發中並沒有使用到,可能理解還不夠准確,只能靠后續不斷糾正了。
1、什么是POJO ?
POJO(Plain Old Java Object)這種叫法是Martin Fowler、Rebecca Parsons和Josh MacKenzie在2000年的一次演講的時候提出來的。
按照Martin Fowler的解釋是“Plain Old Java Object”,從字面上翻譯為“純潔老式的Java對象”,但大家都使用“簡單java對象”來稱呼它。POJO的內在含義是指:那些沒有繼承任何類、也沒有實現任何接口,更沒有被其它框架侵入的java對象。
先給一個定義吧:
POJO是一個簡單的、普通Java對象,它包含業務邏輯處理或持久化邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色,不繼承或不實現任何其它Java框架的類或接口。 可以包含類似與JavaBean屬性和對屬性訪問的setter和getter方法的。
POJO(Plain Old Java Object)這個名字用來強調它是一個普通java對象,而不是一個特殊的對象。
2005年11月時,“POJO”主要用來指代那些沒用遵從特定的Java對象模型,約定或框架如EJB的Java對象。
理想地講,一個POJO是一個不受任何限制的Java對象(除了Java語言規范)。例如一個POJO不應該是
1. 擴展預定的類,如 public class Foo extends javax.servlet.http.HttpServlet { ...
2. 實現預定的接口,如 public class Bar implements javax.ejb.EntityBean { ...
3. 包含預定的標注,如 @javax.ejb.Entity public class Baz{ ...
然后,因為技術上的困難及其他原因,許多兼容POJO風格的軟件產品或框架事實上仍然要求使用預定的標注,譬如用於更方便的持久化。
一般在web應用程序中建立一個數據庫的映射對象時,我們只能稱它為POJO。
正確官方理解思路:
我在做Java EE培訓中,發現我的很多學生問我什么是POJO,后來我在寫書的時候發現POJO這個概念無法回避。現在網上對於POJO的解釋很多,但是很多都是有錯誤的或者不夠准確。
對此我一開始也是存在誤區的,我原來是這樣理解的: POJO是這樣的一種“純粹的”JavaBean,在它里面除了JavaBean規范的方法和屬性沒有別的東西,即private屬性以及對這個屬性方法的public的get和set方法。我們會發現這樣的JavaBean很“單純”,它只能裝載數據,作為數據存儲的載體,而不具有業務邏輯處理的能力。所以下面的代碼被認為是POJO了。
package com.demo.spring;
public class DbHello implements Hello { //實現了接口,就不能稱之為POJO,這已經不是簡單的Java類了
private DictionaryDAO dao;
public void setDao(DictionaryDAO dao) {
this.dao = dao;
}
}
其實,這樣的認為是錯誤的,我仔細閱讀了《POJOs in Action》這本書的有關部分和POJO的最原始的出處http://martinfowler.com/bliki/POJO.html,The term was coined while Rebecca Parsons, Josh MacKenzie and I were preparing for a talk at a conference in September 2000.
In the talk we were pointing out the many benefits of encoding business logic into regular java objects rather than using Entity Beans.We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it''s caught on very nicely.
基本的意思是,將業務邏輯寫進規則的Java對象(regular java objects)中,比使用Entity Beans更有好處。另外,我們要給具有業務邏輯處理的規則的Java對象(regular java objects)起了一個名字——POJO,這些Java對象不是EntityBeans(EJB規范中專門用於封裝數據庫訪問的一種組件,以面向對象的方式進行數據庫的訪問)。
我又在http://www.webopedia.com/TERM/P/POJO.htm查到解釋如下:
POJO, or Plain Old Java Object, is a normal Java object class (that is, not a JavaBean, EntityBean etc.) and does not serve any other special role nor does it implement any special interfaces of any of the Java frameworks. This term was coined by Martin Fowler, Rebbecca Parsons and Josh MacKenzie who believed that by creating the acronym POJO, such objects would have a "fancy name", thereby convincing people that they were worthy of use.
基本意思是說POJO一個普通的Java對象(不是JavaBean,EntityBean等),也不擔當任何的特殊的角色,也不實現任何Java框架指定的接口。
我覺得上面的解釋很准確,POJO應該不是我們開始認為的JavaBean,當然更不是EJB,它不應該依賴於框架(即繼承或實現某些框架類或接口)。總之,POJO就是一個很簡單的Java類,沒那么多復雜的東西。例如:Struts1中的Action和ActionForm當然不屬於POJO了,而在Struts2中的Action由於可以不繼承任何的接口,所以在這種情況下Action是POJO,但是Struts2中的Action也可以繼承ActionSupport類就不再屬於POJO了。POJO里面是可以包含業務邏輯處理和持久化邏輯,也可以包含類似與JavaBean屬性和對屬性訪問的set和get方法的。
最后,我們總結一下給一個定義把,POJO是一個簡單的、普通Java對象,它包含業務邏輯處理或持久化邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色,不繼承或不實現任何其它Java框架的類或接口。
POJO例子:
package com.demo.spring;
public class DbHello { //簡單的Java類,稱之為POJO,不繼承,不實現接口
private DictionaryDAO dao;
public void setDao(DictionaryDAO dao) {
this.dao = dao;
}
}
輔助理解:POJO可以認為是一個中間對象:
一個中間對象,可以轉化為PO、DTO、VO。
1 .POJO持久化之后==〉PO(在運行期,由Hibernate中的cglib動態把POJO轉換為PO,PO相對於POJO會增加一些用來管理數據庫entity狀態的屬性和方法。PO對於programmer來說完全透明,由於是運行期生成PO,所以可以支持增量編譯,增量調試。)
2 .POJO傳輸過程中==〉DTO
3 .POJO用作表示層==〉VO
版權聲明:本文為博主(chunlynn)原創文章,轉載請注明出處 https://blog.csdn.net/chenchunlin526/article/details/69939337
2、什么是JavaBean?
JavaBean實際上是指一種特殊的Java類,它通常用來實現一些比較常用的簡單功能,並可以很容易的被重用或者是插入其他應用程序中去。所有遵循“一定編程原則”的Java類都可以被稱作JavaBean。
JavaBean是一個遵循特定寫法的Java類,是一種Java語言編寫的可重用組件,它的方法命名,構造及行為必須符合特定的約定:
1、這個類必須具有一個公共的(public)無參構造函數;
2、所有屬性私有化(private);
3、私有化的屬性必須通過public類型的方法(getter和setter)暴露給其他程序,並且方法的命名也必須遵循一定的命名規范。
4、這個類應是可序列化的。(比如可以實現Serializable 接口,用於實現bean的持久性)
JavaBean在Java EE開發中,通常用於封裝數據,對於遵循以上寫法的JavaBean組件,其它程序可以通過反射技術實例化JavaBean對象(內省機制),並且通過反射那些遵循命名規范的方法,從而獲知JavaBean的屬性,進而調用其屬性保存數據。
因為這些要求主要是靠約定而不是靠實現接口,所以許多開發者把JavaBean看作遵從特定命名約定的POJO。(可以這么理解,POJO按JavaBean的規則來,就可以變成JavaBean)。
簡而言之,當一個POJO可序列化,有一個無參的構造函數,使用getter和setter方法來訪問屬性時,他就是一個JavaBean。(沒毛病!)
------------------------------------
JavaBean是一種組件技術,就好像你做了一個扳手,而這個扳手會在很多地方被拿去用,這個扳子也提供多種功能(你可以拿這個扳手扳、錘、撬等等),而這個扳手就是一個組件。
◇對於JavaBean,就是一個Java模型組件,他為使用Java類提供了一種標准的格式,在用戶程序和可視化管理工具中可以自動獲得這種具有標准格式的類的信息,並能夠創建和管理這些類。
◇JavaBean可以使應用程序更加面向對象,可以把數據封裝起來,把應用的業務邏輯和顯示邏輯分離開,降低了開發的復雜程度和維護成本!
◇JavaBean 是一種JAVA語言寫成的可重用組件。為寫成JavaBean,類必須是具體的和公共的,並且具有無參數的構造器。JavaBeans 通過提供符合一致性設計模式的公共方法將內部域暴露稱為屬性。眾所周知,屬性名稱符合這種模式,其他Java 類可以通過內省機制發現和操作這些JavaBean 屬性。
◇通常情況下,由於 Java Bean 是被容器所創建(如 Tomcat) 的,所以 Java Bean 應具有一個無參的構造器,另外,通常 Java Bean 還要實現 Serializable 接口用於實現 Bean 的持久性。 Java Bean 是不能被跨進程訪問的。
◇JavaBean 是使用 java.beans 包開發的,它是 Java 2 標准版的一部分。JavaBean 是一台機器上同一個地址空間中運行的組件。JavaBean 是進程內組件。
3、什么是Bean?
Bean的中文含義是“豆子”,Bean的含義是可重復使用的Java組件。所謂組件就是一個由可以自行進行內部管理的一個或幾個類所組成、外界不了解其內部信息和運行方式的群體。使用它的對象只能通過接口來操作。
Bean並不需要繼承特別的基類(BaseClass)或實現特定的接口(Interface)。Bean的編寫規范使Bean的容器(Container)能夠分析一個Java類文件,並將其方法(Methods)翻譯成屬性(Properties),即把Java類作為一個Bean類使用。Bean的編寫規范包括Bean類的構造方法、定義屬性和訪問方法編寫規則。
Java Bean是基於Java的組件模型,由屬性、方法和事件3部分組成。在該模型中,JavaBean可以被修改或與其他組件結合以生成新組件或完整的程序。它是一種Java類,通過封裝成為具有某種功能或者處理某個業務的對象。因此,也可以通過嵌在JSP頁面內的Java代碼訪問Bean及其屬性。
4、什么是EJB 、Entity Bean?
Enterprise Bean,也就是Enterprise JavaBean(EJB),是J2EE的一部分,定義了一個用於開發基於組件的企業多重應用程序的標准。其特點包括網絡服務支持和核心開發工具(SDK)。
在 J2EE里,Enterprise Java Beans(EJB)稱為Java 企業Bean,是Java的核心代碼,分別是會話 Bean(Session Bean),實體Bean(Entity Bean)和消息驅動Bean(MessageDriven Bean)。
1.Session Bean用於實現業務邏輯,它可以是有狀態的,也可以是無狀態的。每當客戶端請求時,容器就會選擇一個Session Bean來為客戶端服務。Session Bean可以直接訪問數據庫,但更多時候,它會通過Entity Bean實現數據訪問。 這個類一般用單例模式來實現,因為每次連接都需要用到它。
2.Entity Bean是域模型對象,用於實現O/R映射,負責將數據庫中的表記錄映射為內存中的Entity對象,事實上,創建一個Entity Bean對象相當於新建一條記錄,刪除一個 Entity Bean會同時從數據庫中刪除對應記錄,修改一個Entity Bean時,容器會自動將Entity Bean的狀態和數據庫同步。
Enterprise Bean 是使用 javax.ejb 包開發的,它是標准 JDK 的擴展,是 Java 2 Enterprise Edition 的一部分。Enterprise Bean 是在多台機器上跨幾個地址空間運行的組件。因此 Enterprise Bean 是進程間組件。
我們一般所熟悉的tomcat僅僅只實現了j2ee的一小部分規范,它只是一個serlvet的容器(Web)容器,它不能跑J2EE的程序,EJB說到底也是種規范,它是j2EE下面的一個子分類(核心類),所以j2ee包含EJB,同時我們都可以說JBOSS,Weblogic,WebSphere是J2EE容器,也可以叫EJB容器。因為它們能跑EJB組件。那么什么是EJB組件呢?其實就是java寫出來的一段程序被打包成EAR包,這個EAR包放在某個EJB的容器的特定目錄下啟動就可以跑了。類似於互聯網公司經常使用的WAR包(部署在tomcat上)。
然后要說的是EJB是一種是很老、很繁瑣的技術標准(規范)了,現如今基本已經被淘汰了。因為EJB的繁瑣、難用,spring的出現徹底革了EJB的命,不然怎么說是Java的春天(spring)來了呢。
EJB實現原理: 就是把原來放到客戶端實現的代碼放到服務器端,並依靠RMI進行通信。
這篇博文對EJB的原理和實質的解釋非常清晰 : http://blog.csdn.net/jojo52013145/article/details/5783677
5、什么是PO?
PO :persistent object持久對象。
O/R Mapping 是 Object Relational Mapping(對象關系映射)的縮寫。通俗點講,就是將對象與關系數據庫綁定,用對象來表示關系數據。
PO是在O/R映射的時候出現的概念,如果沒有O/R映射,沒有這個概念存在了。常用的O/R映射框架有hibernate等。通常對應數據模型(數據庫),本身還有部分業務邏輯的處理。可以看成是與數據庫中的表相映射的java對象。最簡單的PO就是對應數據庫中某個表中的一條記錄,多個記錄可以用PO的集合。PO中應該不包含任何對數據庫的操作。
1、有時也被稱為Data對象,對應數據庫中的entity,可以簡單認為一個PO對應數據庫中的一條記錄。
2、在hibernate持久化框架中與insert/delet操作密切相關。
3、PO中不應該包含任何對數據庫的操作。
4、PO的屬性是跟數據庫表的字段一一對應的。
5、PO對象需要實現序列化接口。
就是說在一些Object/Relation Mapping工具中,能夠做到維護數據庫表記錄的persisent object完全是一個符合Java Bean規范的純Java對象,沒有增加別的屬性和方法。全都是這樣子的:
public class User {
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;
}
}
6、什么是DTO?
DTO (TO) :Data Transfer Object 數據傳輸對象。
主要用於遠程調用等需要大量傳輸對象的地方。
可以將PO中的部分屬性抽取出來,就形成了DTO。
比如我們一張表有100個字段,那么對應的PO就有100個屬性。
但是我們界面上只要顯示10個字段,客戶端用WEB service來獲取數據,沒有必要把整個PO對象傳遞到客戶端,這時我們就可以用只有這10個屬性的DTO來傳遞結果到客戶端,這樣也不會暴露服務端表結構.到達客戶端以后,如果用這個對象來對應界面顯示,那此時它的身份就轉為VO(View Object)。
用在需要跨進程或遠程傳輸時,它不應該包含業務邏輯。
比如一張表有100個字段,那么對應的PO就有100個屬性(大多數情況下,DTO 內的數據來自多個表)。但view層只需顯示10個字段,沒有必要把整個PO對象傳遞到client,這時我們就可以用只有這10個屬性的DTO來傳輸數據到client,這樣也不會暴露server端表結構。到達客戶端以后,如果用這個對象來對應界面顯示,那此時它的身份就轉為VO(View Object)。
7、什么是VO?
VO :value object 值對象 / view object 表現層(視圖)對象。
先說 value object 值對象:
通常用於業務層之間的數據傳遞,和PO一樣也是僅僅包含數據而已。但應是抽象出的業務對象,可以和表對應,也可以不,這根據業務的需要。個人覺得同DTO(數據傳輸對象),在web上傳遞。
①VO(value object)是值對象,精確點講它是業務對象,是存活在業務層的,是業務邏輯使用的,它存活的目的就是為數據提供一個生存的地方。VO的屬性是根據當前業務的不同而不同的,也就是說,它的每一個屬性都一一對應當前業務邏輯所需要的數據的名稱。
VO是什么?它是值對象,准確地講,它是業務對象,是生活在業務層的,是業務邏輯需要了解,需要使用的,再簡單地講,它是概念模型轉換得到的。
首先說PO和VO吧,它們的關系應該是相互獨立的,一個VO可以只是PO的部分,也可以是多個PO構成,同樣也可以等同於一個PO(當然我是指他們的屬性)。正因為這樣,PO獨立出來,數據持久層也就獨立出來了,它不會受到任何業務的干涉。又正因為這樣,業務邏輯層也獨立開來,它不會受到數據持久層的影響,業務層關心的只是業務邏輯的處理,至於怎么存怎么讀交給別人吧!不過,另外一點,如果我們沒有使用數據持久層,或者說沒有使用hibernate,那么PO和VO也可以是同一個東西,雖然這並不好。
② VO(view object)表現層對象,視圖對象。
用一個VO對象對應整個界面的值。
1、主要對應頁面顯示(web頁面/swt、swing界面)的數據對象。
2、可以和表對應,也可以不,這根據業務的需要。
注 :在struts中,用ActionForm做VO,需要做一個轉換,因為PO是面向對象的,而ActionForm是和view對應的,要將幾個PO要顯示的屬性合成一個ActionForm,可以使用BeanUtils的copy方法。
8、什么是DAO?
DAO :data access object 數據訪問對象。
這個大家最熟悉,和上面幾個O區別最大,基本沒有互相轉化的可能性和必要.
主要用來封裝對數據庫的訪問。通過它可以把POJO持久化為PO,用PO組裝出來VO、DTO。
是一個sun的一個標准j2ee設計模式,這個模式中有個接口就是DAO,它負持久層的操作。為業務層提供接口。此對象用於訪問數據庫。通常和PO結合使用,DAO中包含了各種數據庫的操作方法。通過它的方法,結合PO對數據庫進行相關的操作。夾在業務邏輯與數據庫資源中間。配合VO,提供數據庫的CRUD操作...
1、主要用來封裝對DB(數據庫)的訪問(CRUD操作)。
2、通過接收業務層的數據,把POJO持久化為PO。
9、什么是BO?
JavaBean是一種組件技術,就好像你做了一個扳手,而這個扳手會在很多地方被拿去用,這個扳子也提供多種功能(你可以拿這個扳手扳、錘、撬等等),而這個扳手就是一個組件。
BO :business object 業務對象。
主要作用是把業務邏輯封裝為一個對象。這個對象可以包括一個或多個其它的對象。
比如一個簡歷,有教育經歷、工作經歷、社會關系等等。
我們可以把教育經歷對應一個PO,工作經歷對應一個PO,社會關系對應一個PO。
建立一個對應簡歷的BO對象處理簡歷,每個BO包含這些PO。
這樣處理業務邏輯時,我們就可以針對BO去處理。
封裝業務邏輯的java對象,通過調用DAO方法,結合PO,VO進行業務操作。
封裝業務邏輯為一個對象(可以包括多個PO,通常需要將BO轉化成PO,才能進行數據的持久化,反之,從數據庫中得到的PO,需要轉化成BO才能在業務層使用)。
關於BO主要有三種概念
1 、只包含業務對象的屬性;
2 、只包含業務方法;
3 、兩者都包含。
在實際使用中,認為哪一種概念正確並不重要,關鍵是實際應用中適合自己項目的需要。
版權聲明:本文為博主(chunlynn)原創文章,轉載請注明出處 https://blog.csdn.net/chenchunlin526/article/details/69939337
————————————————
版權聲明:本文為CSDN博主「chunlynn」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/chenchunlin526/article/details/69939337