is DTO an antipattern in EJB 3.0 ?

来源:互联网 发布:长兴古银杏王数据 编辑:程序博客网 时间:2024/05/20 19:49


這個問題應該是從 Raghu Kodali's blog 開始的

http://www.jroller.com/page/raghukodali?entry=dto_an_antipattern_in_ejb

Raghu 的論述主要在於, Design Pattern 中的 Data Transfer Objects (DTO) 原本是要避免重新取得舊有的 EJB2.x 的遠端呼叫時間, 讓 DTO 封裝資料後送到客戶端處理. 不過,  當資料量過大的時候, DTOs 卻顯得龐大而難用, 一股腦地將所有資料封裝整堆送到客戶端.. 這難道是唯一的方法嗎 ?

因為 Java Persistence API (ejb3 entities) 目前就是一個 POJO , 為何需要重新建立一個 DTO 呢? 利用 EntityManager 便可以簡單地透過 create/ remove/ find 以及 query 的方式來存取需要的資料, 也可以利用 merge 的方式來更改 Object 的狀況. 因為 EJB3.0 的 persistence 可以定義為 Attached/Detached/Reattached 到資料庫之中, 因此, 讓 client 擁有 detached entities 就可以取代了 DTOs  .

基本上, 以客觀的角度認為, DTOs 面對 Detached Objects 的 entities, 顯得比較沒有意義, 不過, 不使用 DTOs 這種方式可能會造成另一個麻煩, 就會讓 Transaction 的動作交到 client-tier 作處理, 如果屬於 @OneToMany 的 Objects, 我被迫一定得利用 EAGER 的方式讓所有的資料產出, 而無法採用 LAZY 的模式進行關聯式存取.

換句話說, 我們原本可以在 SessionBean 同一個 Transaction 之中過濾相關的資料, 以 Lazy 的模式取得應該要的資料, 將有效的資料放到 DTOs 再拋給 Client-Tier..

然而, 因為 PersistenceContext 可以設定為 TransactionScope 或 extended, 往往 Stateless 是設定為 TransactionScope, Stateful 是設定為 extended, 就是希望 Stateful 的情況, 無須重新取得 PersistenceContext . 不過不用太擔心 Stateless TransactionScope 的狀況, 因為 Detached Lifecycle 是可以透過 merge 的方式回到 Managed 的 Lifecycle 之中.

總結 ~

在一般狀況來看, 資料量與關聯性都不高的情況, 我們利用 Detached Object 取代 DTOs 的確無可厚非, 但是如果會因為關聯性取得大量資料, 想使用 LAZY 的 FetchType, 在同一個 Transaction 之中處理完畢, 那麼, DTOs 就是比較好的 Patterns.  因此, is DTO an antipattern in EJB3.0 ? 看你的系統整體架構吧 !