作者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)
1F:推 jini:qrtt1 说得真好 05/31 00:07
2F:推 etman395:写的真好 我恍然大悟!! 05/31 14:25
※ 编辑: qrtt1 来自: 61.231.55.86 (05/31 16:06)