1. 程式人生 > >【Java-POJO-設計模式】JavaEE中的POJO與設計模式中多型繼承的衝突

【Java-POJO-設計模式】JavaEE中的POJO與設計模式中多型繼承的衝突

最近看《重構》談到利用OO的多型來優化 if else 和 switch 分支語句,但是我發現OO語法中的多型在使用框架的JavaEE中是無法實踐的。對此,我感到十分的疑惑,加之之前專案中有個“狀態模式”類的模組被頻繁改動的需求折磨要死,又去看了《設計模式》。《設計模式》中也是強調,使用多型和繼承來實現“狀態”模式。但在採用了 SSH 或 SSM 的專案中,但我從來沒有在 實體類(POJO/Bean)中見到過“繼承”的語法形式。   於是,我搜集了所謂 POJO 、JavaBean、VO、PO、DTO這幾個相近概念的含義。  
  POJO    一:什麼是POJO
POJO的名稱有多種,pure old java object 、plain ordinary java object 等。
按照Martin Fowler的解釋是“Plain Old Java Object”,從字面上翻譯為“純潔老式的java物件”,但大家都使用“簡單java物件”來稱呼它。
POJO的內在含義是指那些沒有從任何類繼承、也沒有實現任何介面,更沒有被其它框架侵入的java物件。

 

二:為什麼會有POJO?
主要是Java的開發者被EJB的繁雜搞怕了,大家經過反思,又迴歸“純潔老式”的JavaBean,即有無參建構函式,每個欄位都有getter和setter的java類。

 

三:POJO的意義
POJO讓開發者可專注於業務邏輯和脫離框架的單元測試。除此之外, 由於POJO並不須要繼承框架的類或實現其介面,開發者能夠極其靈活地搭建繼承結構和建造應用。
POJO的意義就在於它的簡單而靈活性,因為它的簡單和靈活,使得POJO能夠任意擴充套件,從而勝任多個場合,也就讓一個模型貫穿多個層成為現實。
先寫一個核心POJO,然後實現業務邏輯介面和持久化介面,就成了Domain Model; UI需要使用時,就實現資料繫結介面,變成VO(View Object)。

 

四:POJO與PO、VO的區別
POJO是指簡單java物件(Plain Old Java Objects、pure old java object 或者 plain ordinary java object)。
PO是指持久物件(persistant object持久物件)。
VO是指值物件或者View物件(Value Object、View Object)。注意,本文的VO特指View Object。
持久物件實際上必須對應資料庫中的entity,所以和POJO有所區別。比如說POJO是由new建立,由GC回收。但是持久物件是insert資料庫建立,由資料庫delete刪除的。基本上持久物件生命週期和資料庫密切相關。另外持久物件往往只能存在一個數據庫Connection之中,Connnection關閉以後,持久物件就不存在了,而POJO只要不被GC回收,總是存在的。
由於存在諸多差別,因此持久物件PO(Persistent Object)在程式碼上肯定和POJO不同,起碼PO相對於POJO會增加一些用來管理資料庫entity狀態的屬性和方法。而ORM追求的目標就是要PO在使用上儘量和POJO一致,對於程式設計師來說,他們可以把PO當做POJO來用,而感覺不到PO的存在。

 

五:POJO的擴充套件
POJO僅包含最簡單的欄位屬性,沒有多餘的東西,它本質上就是一個普通的JavaBean。
但是在POJO的基礎上,能夠擴展出不同的物件。
為POJO增加了持久化的方法(Insert、Update、Delete……)之後,POJO就變成了PO。
為POJO增加了資料繫結功能之後,POJO就變成了View Object,即UI Model。
為POJO增加業務邏輯的方法(比如單據稽核、轉帳……)之後,POJO就變成了Domain Model。
POJO還可以當作DTO使用。

 


 

 

我一直認為:概念,名詞,理論無非是人用來理解、抽象事物的,是拿來用的。如果沒有相應的名詞,我們自己也可以創造。

 

個人感覺,在SSM或SSH的 JavaWeb 專案中,領域模型【Domain Model】(如成績管理系統裡面的學生、成績等實體) 一般是被簡化為 POJO ,然後這個 POJO 既用作 VO 也用作 PO 。Struts 或 Sprint MVC 用 VO 來包裹頁面的資料,傳給 Action  或 Controller ; Action  或 Controller 內部 用 DTO【Data Transfer Object 】互相傳輸資料; Hibernate 或者 MyBatis 用 PO 來包裹 業務邏輯處理過的資料 放到 資料庫中。在這裡,VO 和 PO 因為簡單,就使用同一個 POJO 了事。但是如果我們遇到複雜的 領域模型,這個需要使用 繼承和多型的 結構應該放在哪裡呢 ?  POJO ? PO?VO?DTO?我覺得,這時候,是不是就應該需要另外一層 ?

 

舉個在《設計模式:Java語言》中的“狀態模式”的例子。

有個傳送帶,它有一個用於放入物品的門和控制門開關的按鈕。當門關著時,按鈕開門;當門開著時,按鈕使門繼續保持開啟;當門開著,且2分鐘沒有操作時,門自動關閉;當門正在關閉時,按鈕使門開啟;當門正在開啟時,按鈕開門。【具體細節忘了。。。】

博主:簡單的說,就是按鈕總是要開門,門超時會自動關閉。門除了開關兩個狀態,還有“正在開 Opening ”  和 “正在關 Closing”兩個狀態。

書中建議使用 狀態模式,也就是說需要 設計 含有繼承關係的幾個類。如果這個功能出現在採用了 SSM 框架的 JavaEE專案中,那麼,這個繼承關係該設計到哪裡呢?