作者qrtt1 (null)
看板java
標題Re: [問題] DAO 模式
時間Sat May 30 22:43:32 2009
※ 引述《etman395 (技術時代)》之銘言:
: 噗
: 謝謝解說= =
: 我的理解是這樣
: 有問題糾正我一下 謝謝= =
: 一個dao介面抽象出所有資料表裡面可能操作的方法
: 再一個實作dao介面的類別實作出
: 然後再寫一個user類別封裝該資料表 user表
: 接著把使用者的參數放該user類別
: 然後呼叫 實作dao介面方法插user類別 之後從user裡面拿出參數帶入sql語句
: 從上面看來我只感覺的出來的好處
: 就是不用在jsp裡面打sql代碼
: 然後因為有了dao介面
: 換資料庫只要修改實作dao的方法
: 好處就以上二點是嗎??
: 上面我全都用推的
: 推dao在做的是什麼
: 然後怎麼分離而己
: 其實我不確定是不是這樣做
基本上的理解大致是對的,但是少了點什麼。
缺少的是 pattern 互動的角色,以致內心戲的劇本無法完整演譯。
為什麼要有 dao pattern?可以先問自己一個基本的問題。
pattern 是有系統地整理前人開發經驗的結果,
回顧開發歷程,最令人痛苦的是需求「變更」帶來的實作改變。
對於資料庫程式應用更是如此,
簡單如新增一個查詢,您可能只需要多寫一個 SQL
較麻煩如資料庫轉換,可能應擴充的需要
或區分測試、開發環境需要在不同資料庫切換。
SQL 語法間的差異讓您不得不做出些微的改變。
在 jsp 內直接下 SQL 當然是最直接取得資料的方式,
蠻多的入門書也是這樣寫。
實際上,有許多理由您不該那麼寫。
因為 SQL 會散落在 jsp 檔內,當變動產生的時候
您需要一一地去改變多個 jsp 檔內的 SQL
這是未使用 dao 時最大的麻煩。
這裡所指的 dao 並不是嚴格地 dao pattern 規範,
而是一層「間接」的物件,透過它來與實際的資料庫互動
所以使用
<jsp:useBean ... />
封裝與資料庫的互動行為也是一種 dao 的實現。
這樣的寫法,當變動產生時,您只要改變 Bean 的實作。
======================================================
http://java.sun.com/blueprints/corej2eepatterns/
Patterns/DataAccessObject.html
(
http://tinyurl.com/merh )
您可以參考一下 figure 9.2
它有幾個角色:
1. BusinessObject
2. DAO
3. DataSource
4. TansferObject
依您理解的描述,您把焦點放在 2, 3, 4 的角色
[2] ::
一個dao介面抽象出所有資料表裡面可能操作的方法
再一個實作dao介面的類別實作出
[4] ::
然後再寫一個user類別封裝該資料表 user表
接著把使用者的參數放該user類別
[2]->[3]->[4]
然後呼叫 實作dao介面方法插user類別
之後從user裡面拿出參數帶入sql語句
=====================================================
當您忽略角色 [1] 時,只會覺得本來寫的那樣就可以用了
為什麼要再那麼累,生個 dao 出來,又再多個 domain model 放資料
開始懷疑這麼做是不是很彆扭,需要一些背書過的好處加強信心。
BusinessObject 的角色是什麼?
雖然我們借用 Java EE 定義的 DAO作說明,
並非真的需要多一個 Business Layer (Service Layer) 使用 DAO
純化的角色就是 [1] 是 dao 的使用者(client)
在您的例子就是 jsp (view layer)。
在 pattern 應用裡,最爽的就是 client 角色。
在正確使用 pattern 的情況下,受改變影響最小的應該是 client
變動會被被封裝在 pattern 的實作內。
因此,實作 pattern 是一件「爽到 client 甘苦到實作者的事」
不過通常我們不太會享受到容易更換資料庫的好處
因為這件事的成本總是比預想的高。
對 client 來說,
操作資料來源(data source:db、file、ldap、s3) 細節不會到處散落
像是換 JdbcDriver 版本、資料庫連線設定、SQL 語法微調
都只在 DAO 或它的背後做改變。
對 dao 來說,
它可以獨立於 client 實行重構、單元測試。
您不再需要啟動完整的環境(web server + data source + user behavior)
您可以單純以 dao(+data source) + method invoke 單純驗證邏輯
少開一個 web server 與人工觸發 view 測試會省去許多時間。
因為您開的可能是一個怪物級的 web server,
它可能會吃掉許多資源,這就限制了您的開發環境需要「高檔」一些
而省去人工開 jsp page 測試,可以減低肩腕的使用達到保護的效果
當您不再那麼人工地實行開發時,
恭禧!您已經脫離黑手,成為開發者。
多出來的時間可以和 OL 聊天,或是裝忙等下班 :P
: ※ 引述《adrianshum (Alien)》之銘言:
: : DAO 簡而言之, 就是我寫的logic 不用再管
: : CRUD 的部份, 把 CRUD 交給一個 DAO. 某程度
: : 上, 我的 logic 就不再需要理會背後用什麼
: : persistence technology, 以後想比如換用別的
: : DB, 只要換別的 DAO Impl 就好了. 感覺上就像:
: : (Logic): 好, 建好一部車的資料了, DAO, 幫我
: : 存好它:
: : (DAO): 哦 (然後自己默默用 SQL 插入 DB)
: : 或者
: : (Logic): DAO, 幫我拿出所有紅色的車子
: : (DAO): 哦 (然後自己默默用 SQL 找出 record,
: : 把 record 轉為車子)
: : 諾, 你要的車子
: : (Logic): 好! (然後繼續工作)
: : interface CarDao {
: : void createCar(Car car);
: : List<Car> findCarsByColor(Color color);
: : }
: : class CarDaoOracleImpl implements CarDao {
: : // Oracle 的 sql 實作
: : }
: : class CarDaoMySqlImpl implements CarDao {
: : // My SQL 的 sql 實作
: : }
: : 概念就這樣
: : 最重要是 DAO 要把背後 persistence 的 techonlogy
: : 隱藏起來, 比如看過有些人寫 DAO, return 的是
: : resultset, 又或者傳進一句 SQL 來做 query,
: : 這些就是換湯不換藥的做法, 對架構一點幫助都沒有.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.231.55.86
※ 編輯: qrtt1 來自: 61.231.55.86 (05/30 22:46)
※ 編輯: qrtt1 來自: 61.231.55.86 (05/30 22:47)
推 jini:qrtt1 說得真好 05/31 00:07
推 etman395:寫的真好 我恍然大悟!! 05/31 14:25
※ 編輯: qrtt1 來自: 61.231.55.86 (05/31 16:06)