摘要:淺析POJO、DTO、DO、VO、BO、PO和Entity等的概念、區別及其用法。
名詞解釋
領域模型中的實體類分為四種模型:VO、DTO、DO和PO,各種實體類用於不同業務層次間的交互,並會在層次內實現實體類之間的轉化。新項目使用了新的框架和開發規范,特意集體討論了DTO,DO,VO,BO,POJO,PO和Entity以及DAO、Model和View的基本概念和使用場景,為了深入理解,這里整理為一篇筆記。下面通過一張圖看一下它們的大致分類:
用MVC模式的角度接着看圖,看完圖估計大部分人對這些專業術語就有一個直觀的感受了:
POJO
總的來說,普通Java對象POJO(Pure Old Java Object 、 Plain Ordinary Java Object),按照Martin Fowler的解釋是“Plain Old Java Object”,從字面上翻譯為“純潔老式的java對象”,但大家都使用“簡單java對象”來稱呼它。包含DO、DTO、BO、VO和PO等,它們本質上都是一個簡單的java對象,實際就是普通的JavaBeans。沒有業務邏輯,有時可以作為VO或DTO來使用。當然,這里特意說明純普通Java對象,如果你有一個簡單的運算屬性也是可以的,但不允許有業務方法。
POJO是指這樣的java對象:
- 有一些private的參數作為對象的屬性
- 針對每一個參數定義get和set方法
- 沒有從任何類繼承
- 沒有實現任何接口
- 沒有被其它框架侵入。
許多開發者把JavaBean看作遵從特定命名約定的POJO。例如:
public class User {
private Long id;
private String userName;
private String msg;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
POJO其實是比javabean更純凈的簡單類或接口。POJO嚴格地遵守簡單對象的概念,而不具有業務邏輯處理的能力,而一些JavaBean中往往會封裝一些簡單邏輯。例如,改造User后,可以得到一個JavaBean:
public class User implements Serializable {
//實現serializable接口
private static final long serialVersionUID = -2241142936329900646L;
private Long id;
private String userName;
private String msg;
private Integer age;
/**
* 無參構造器
*/
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User(Long id, String userName, Integer age) {
this.id = id;
this.userName = userName;
this.age = age;
}
}
VO
VO(View Object)視圖模型,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。如果是一個DTO對應一個VO,則DTO等價於VO;但是如果一個DTO對應多個VO,則展示層需要把VO轉換為服務層對應方法所要求的DTO,傳送給服務層,從而達到服務層與展示層解耦的效果。
一般用在業務邏輯層(Service)對前端(Web) 的視圖模型效果控制的展示上,說白了就是后台向前端傳輸數據。示例:xxxVO,xxx一般為網頁名稱。注:在展示業務不復雜的系統,可直接使用DTO。
DTO
數據傳輸對象DTO(Data Transfer Object)是一個比較特殊的對象,它有兩種存在形式:在后端,它的存在形式是java對象,也就是在controller里面定義的請求參數,通常在后端不需要關心怎么從json轉成java對象的,這個都是由一些成熟的框架幫你完成啦,比如spring框架;在前端,它的存在形式通常是js里面的對象(也可以簡單理解成json),即通過ajax請求的那個數據體。這也是為什么把他畫成橫跨兩層的原因。舉個例子,xxxDTO,xxx為業務領域相關的名稱。
現在微服務盛行,服務和服務之間調用的傳輸對象能叫DTO嗎?我的理解是看情況,DTO的一個隱含意義是要能夠完整的表達一個業務模塊的輸出。如果服務和服務之間相對獨立,那就可以叫DTO;如果服務和服務之間不獨立,每個都不是一個完整的業務模塊,拆開可能僅僅是因為計算復雜度或者性能的問題,那這就不能夠叫做DTO,只能是BO。
DTO與BO或者DO的區別是DTO沒有任何行為(方法),只是存儲和提供它所擁有數據的查詢(訪問器和修改器)。DTO是簡單對象,不包含任何需要測試的業務邏輯。
Entity/PO
持久化對象PO(Persistent Object)等同於Entity,它們的概念是一致的。數據庫表中的記錄在java對象中的顯示狀態。最形象的理解就是一個PO對象對應數據庫中的一條記錄,一個PO的數據結構對應着庫中一張表的表結構,即自身屬性與數據表字段一一對應。好處是可以把一條記錄作為一個對象處理,方便的轉為其它對象。
例如我們有一條數據,現在有一個簡單類而且已經是被賦予了這條數據的實例,那么這條數據在這個簡單類中的存在狀態就是PO,不管這個簡單類是DO還是BO抑或其它。PO只是數據持久化的一個狀態。
通常PO里面除了get,set之外沒有別的方法。對於PO來說,數量是相對固定的,一定不會超過數據庫表的數量。
DO
領域對象 DO(Domain Object) 是從現實世界中抽象出來的有形或無形的業務實體,它用來接收數據庫對應的實體,是一種抽象化的數據狀態,介於數據庫與業務邏輯之間。
一般在業務邏輯層(Service)對數據庫(SQL) 進行訪問時,用於接收數據。xxxDO,xxx即為數據表名。另外,DO與Entity的不同點就是DO是與數據庫存在着某種映射關系的Entity,總的來說DO是Entity的一種。
現在主要有兩個版本一個是阿里巴巴的開發手冊中定義的DO( Data Object),這個等同於上面的PO;另一個是在DDD(Domain-Driven Design)領域驅動設計中定義的DO(Domain Object),這個等同於上面的BO。
BO
業務對象(Business Object,BO)是對數據進行檢索和處理的組件,主要作用是把業務邏輯封裝為一個對象,這個對象可以包括一個或多個其它的對象。形象描述為一個對象的形為和動作,當然也有涉及到其它對象的一些形為和動作。
BO通常位於中間層或者業務邏輯層。BO支持序列化和反序列化,可以輕易地將BO的Java實例轉換為一個XML文件或者一個流保存起來,並且在需要的時候,將這個BO從XML或者流中轉換回一個Java實例。舉個簡單的例子,一個簡歷包含教育經歷、工作經歷、社會關系等三個模塊,每個模塊對應一個PO;建立一個BO對象處理簡歷,則每個BO包含這三個PO。
應用中的所有實體(Entity)都是BO,但並不是所有BO都是實體。BO包括包含方法的實體對象(Entity Object)和不包含方法的值對象(VO)。
Model
Model是數學邏輯名詞,包括有限操作的集合以及定義於其上的關系,主要用於分析、設計過程。
實體類和模型Model在計算機程序設計中有兩個概念:一個是三層架構中的實體類,另一個是MVC架構中的模型。在“三層架構”中,為了面向對象編程,將各層傳遞的數據封裝成實體類,便於數據傳遞和提高可讀性。在MVC(模型Model-視圖View-控制器Controller)模式中,Model代表模型,是業務流程/狀態的處理以及業務規則的制定,接受視圖請求的數據,並返回最終的處理結果。業務模型的設計可以說是MVC最主要的核心。
View
在MVC模式中,View代表視圖,用來解析Model帶來的數據模型,以展示視圖數據,View的模型覺決定了需要什么樣的Model來對接,相互聯系。
DAO
數據訪問對象DAO (Data Access Object)是一個數據訪問接口,所謂數據訪問,顧名思義,就是與數據庫打交道,夾在業務邏輯與數據庫資源中間。
一般在業務邏輯層對數據庫進行訪問時使用。
xxxDAO,xxx即為實體類名(Entity實體)。在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個健壯的J2EE應用,應該將所有對數據源的訪問操作抽象封裝在一個公共API中。用程序設計的語言來說,就是建立一個接口,接口中定義了此應用程序中將會用到的所有事務方法。在這個應用程序中,當需要和數據源進行交互的時候就使用這個接口,並且編寫一個單獨的類或者xml文件,來實現這個接口在邏輯上對特定數據的操作。
放在哪個目錄
- PO通常放在名為bean、entity、model目錄中。
- DAO通常在DAO、mapper目錄中。
- BO通常在service、manager、business目錄中。
POJO的擴展
POJO僅包含最簡單的字段屬性,沒有多余的東西,它本質上就是一個普通的JavaBean。但是在POJO的基礎上,能夠擴展出不同的對象。
-
為POJO增加了持久化的方法(Insert、Update、Delete……)之后,POJO就變成了PO。
-
為POJO增加了數據綁定功能之后,POJO就變成了View Object,即UI Model。
-
為POJO增加業務邏輯的方法(比如單據審核、轉帳……)之后,POJO就變成了Domain Model。
-
POJO還可以當作DTO使用。
文章到這里就結束了,看完之后你有什么想法想要跟大家分享呢?評論區在等着你!