淺談DAO工廠設(shè)計(jì)模式
Posted on 2008-11-26 08:01 J2EE Home工作室 閱讀(393) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 設(shè)計(jì)模式隨著軟件分層設(shè)計(jì)的流行及廣泛的應(yīng)用,對(duì)于DAO的設(shè)計(jì)模式大家已經(jīng)不再陌生了,DAO層已經(jīng)在軟件系統(tǒng)的開(kāi)發(fā)中成為必不可少的一層,將后臺(tái)的數(shù)據(jù)層和前臺(tái)的VO進(jìn)行分離。前段時(shí)間也針對(duì)于DAO的設(shè)計(jì)介紹過(guò)一個(gè)基于Hibernate的泛型DAO的設(shè)計(jì)。
csdn blog:http://blog.csdn.net/yongtree/archive/2008/03/12/2172071.aspx
javaeye blog:http://yongtree.javaeye.com/blog/170449
通過(guò)DAO的設(shè)計(jì)的確可以讓我們的軟件系統(tǒng)已經(jīng)將數(shù)據(jù)層和表現(xiàn)層進(jìn)行了簡(jiǎn)單的分離,讓我們系統(tǒng)各層次的功能更加的清晰。所以我們開(kāi)始洋洋得意了,DAO的引入讓系統(tǒng)的耦合性更加的松散,表現(xiàn)層再也不需要關(guān)心后臺(tái)數(shù)據(jù)操作的變化了。于是我們開(kāi)始高枕無(wú)憂了,我們肆無(wú)忌憚的在表現(xiàn)層通過(guò)調(diào)用DAO來(lái)實(shí)現(xiàn)我們的系統(tǒng)了。事實(shí)真的如此嗎?那我們就舉個(gè)例子來(lái)看看我們的系統(tǒng)是否真的具有解偶的能力了。
現(xiàn)在我們有個(gè)員工管理系統(tǒng),在該系統(tǒng)中,Person.java表示員工這個(gè)對(duì)象,它對(duì)應(yīng)著數(shù)據(jù)庫(kù)中的person表。還有用于操作Person對(duì)象的DAO接口—PersonDAO.java,還有一個(gè)PersonDAO的實(shí)現(xiàn)類(lèi)PersonDAOImpl.java。在PersonDAOImpl.java中我們實(shí)現(xiàn)了操作Person對(duì)象的所有的方法。我們很自豪的說(shuō),看我們已經(jīng)把操作封裝在PersonDAO中了,現(xiàn)在我們可以在表現(xiàn)層(jsp,或者VO操作類(lèi)中)使用PersonDAO personDAO=new PersonDAOImpl()來(lái)調(diào)用DAO操作我們的數(shù)據(jù)對(duì)象了。當(dāng)我們陶醉于自己寫(xiě)的優(yōu)美的代碼的時(shí)候,項(xiàng)目經(jīng)理來(lái)通知了,由于使用Hibernate的效率偏低,客戶開(kāi)始不滿了,還是讓我們重新用JDBC再重寫(xiě)一遍吧。于是所有DAO的Hibernate實(shí)現(xiàn)開(kāi)始全部轉(zhuǎn)換成JDBC實(shí)現(xiàn)。但是項(xiàng)目經(jīng)理建議不要破壞現(xiàn)有的Hibernate實(shí)現(xiàn),以后可以通過(guò)技術(shù)研究來(lái)提升Hibernate的訪問(wèn)效率。于是我們開(kāi)始寫(xiě)了又寫(xiě)了一套JDBC的實(shí)現(xiàn)—PersonDAOJDBCImpl.java,現(xiàn)在問(wèn)題出來(lái)了,表現(xiàn)層大量的使用了PersonDAO personDAO=new PersonDAOImpl(),全部改成new PersonDAOJDBCImpl()談何容易,我們是不是開(kāi)始欲哭無(wú)淚了。
怎么解決類(lèi)似的問(wèn)題呢?于是我們開(kāi)始引進(jìn)工廠模式。我們建立一個(gè)類(lèi)DaoFactory.java對(duì)DAO進(jìn)行統(tǒng)一管理。
DaoFactory.java:
public class DaoFactory{
public static PersonDAO getPersonDAOInstance()
{
return new PersonDAOImpl() ;
}
//得到其他的DAO實(shí)例
……
}
表現(xiàn)層通過(guò)PersonDAO personDAO=DaoFactory.get getPersonDAOInstance();來(lái)實(shí)例化DAO實(shí)例。這樣問(wèn)題就解決了,DAO改變了,我們只需要在DAO工廠類(lèi)中修改一下代碼:return new PersonDAOJDBCImpl() ;那我們的應(yīng)用就快速切換到JDBC實(shí)現(xiàn)了。可見(jiàn)利用工廠模式,我們的系統(tǒng)又進(jìn)一步的解耦,表現(xiàn)層真的無(wú)需再關(guān)系DAO層的變化了,一切交給DAO工廠來(lái)解決。
使用過(guò)Spring這樣框架的開(kāi)發(fā)人員都知道,Spring通過(guò)利用IoC來(lái)實(shí)現(xiàn)類(lèi)之間的解耦。其實(shí)在DAO工廠中我們也可以簡(jiǎn)單的借鑒一下IoC的思想,更進(jìn)一步解除類(lèi)之間的耦合。Spring是通過(guò)配置xml文件來(lái)進(jìn)行IoC的,那么我們也可以借助于xml文件來(lái)實(shí)現(xiàn)。比如下面的xml:
<?xml version="1.0"?>
<config>
<daos>
<!-- 組織機(jī)構(gòu)服務(wù)接口實(shí)現(xiàn)類(lèi) -->
<dao id="organizationService"
type="com.baiyyy.oa.services.organization.OrganizationServiceImpl">
</dao>
<!-- 工作流參與者接口 -->
<dao id="participantService"
type="com.baiyyy.workflow.services.impl.ParticipantServiceImpl">
</dao>
<!-- 工作流定義接口 -->
<dao id="processDefinitionService"
type="com.baiyyy.workflow.services.impl.ProcessDefinitionServiceImpl">
</dao>
<!-- 工作流實(shí)例接口 -->
<dao id="processInstanceService"
type="com.baiyyy.workflow.services.impl.ProcessInstanceServiceImpl">
</dao>
</daos>
</config>
這是我設(shè)計(jì)實(shí)現(xiàn)的工作流系統(tǒng)給業(yè)務(wù)系統(tǒng)提供的接口所配置的xml,所有的接口都配置在xml中,我們?cè)趺词褂媚兀课抑徊贿^(guò)是把DAO工廠進(jìn)行進(jìn)一步的改進(jìn),通過(guò)ProcessInstanceService processInstanceService=DaoFactory.getDao(ProcessInstanceService.class,” processInstanceService”);從傳入的參數(shù)我們可以看出,我們清楚的知道要調(diào)用的接口ProcessInstanceService,同時(shí)通過(guò)字符串” processInstanceService”,我們可以解析上面的配置文件,得到具體實(shí)現(xiàn)類(lèi)的路徑,通過(guò)反射得到該實(shí)現(xiàn)類(lèi)的實(shí)例。具體的DAO工廠類(lèi)的實(shí)現(xiàn),朋友們有興趣可以自己去實(shí)現(xiàn),我就不詳細(xì)介紹了。
終于寫(xiě)完了,以上便是對(duì)DAO工廠一些淺顯的理解。現(xiàn)在正在學(xué)習(xí)設(shè)計(jì)模式,以后會(huì)根據(jù)自己的所學(xué)所思,介紹自己對(duì)各個(gè)設(shè)計(jì)模式的理解,希望大家一塊學(xué)習(xí)討論。
csdn blog:http://blog.csdn.net/yongtree/archive/2008/03/12/2172071.aspx
javaeye blog:http://yongtree.javaeye.com/blog/170449
通過(guò)DAO的設(shè)計(jì)的確可以讓我們的軟件系統(tǒng)已經(jīng)將數(shù)據(jù)層和表現(xiàn)層進(jìn)行了簡(jiǎn)單的分離,讓我們系統(tǒng)各層次的功能更加的清晰。所以我們開(kāi)始洋洋得意了,DAO的引入讓系統(tǒng)的耦合性更加的松散,表現(xiàn)層再也不需要關(guān)心后臺(tái)數(shù)據(jù)操作的變化了。于是我們開(kāi)始高枕無(wú)憂了,我們肆無(wú)忌憚的在表現(xiàn)層通過(guò)調(diào)用DAO來(lái)實(shí)現(xiàn)我們的系統(tǒng)了。事實(shí)真的如此嗎?那我們就舉個(gè)例子來(lái)看看我們的系統(tǒng)是否真的具有解偶的能力了。
現(xiàn)在我們有個(gè)員工管理系統(tǒng),在該系統(tǒng)中,Person.java表示員工這個(gè)對(duì)象,它對(duì)應(yīng)著數(shù)據(jù)庫(kù)中的person表。還有用于操作Person對(duì)象的DAO接口—PersonDAO.java,還有一個(gè)PersonDAO的實(shí)現(xiàn)類(lèi)PersonDAOImpl.java。在PersonDAOImpl.java中我們實(shí)現(xiàn)了操作Person對(duì)象的所有的方法。我們很自豪的說(shuō),看我們已經(jīng)把操作封裝在PersonDAO中了,現(xiàn)在我們可以在表現(xiàn)層(jsp,或者VO操作類(lèi)中)使用PersonDAO personDAO=new PersonDAOImpl()來(lái)調(diào)用DAO操作我們的數(shù)據(jù)對(duì)象了。當(dāng)我們陶醉于自己寫(xiě)的優(yōu)美的代碼的時(shí)候,項(xiàng)目經(jīng)理來(lái)通知了,由于使用Hibernate的效率偏低,客戶開(kāi)始不滿了,還是讓我們重新用JDBC再重寫(xiě)一遍吧。于是所有DAO的Hibernate實(shí)現(xiàn)開(kāi)始全部轉(zhuǎn)換成JDBC實(shí)現(xiàn)。但是項(xiàng)目經(jīng)理建議不要破壞現(xiàn)有的Hibernate實(shí)現(xiàn),以后可以通過(guò)技術(shù)研究來(lái)提升Hibernate的訪問(wèn)效率。于是我們開(kāi)始寫(xiě)了又寫(xiě)了一套JDBC的實(shí)現(xiàn)—PersonDAOJDBCImpl.java,現(xiàn)在問(wèn)題出來(lái)了,表現(xiàn)層大量的使用了PersonDAO personDAO=new PersonDAOImpl(),全部改成new PersonDAOJDBCImpl()談何容易,我們是不是開(kāi)始欲哭無(wú)淚了。
怎么解決類(lèi)似的問(wèn)題呢?于是我們開(kāi)始引進(jìn)工廠模式。我們建立一個(gè)類(lèi)DaoFactory.java對(duì)DAO進(jìn)行統(tǒng)一管理。
DaoFactory.java:
public class DaoFactory{
public static PersonDAO getPersonDAOInstance()
{
return new PersonDAOImpl() ;
}
//得到其他的DAO實(shí)例
……
}
表現(xiàn)層通過(guò)PersonDAO personDAO=DaoFactory.get getPersonDAOInstance();來(lái)實(shí)例化DAO實(shí)例。這樣問(wèn)題就解決了,DAO改變了,我們只需要在DAO工廠類(lèi)中修改一下代碼:return new PersonDAOJDBCImpl() ;那我們的應(yīng)用就快速切換到JDBC實(shí)現(xiàn)了。可見(jiàn)利用工廠模式,我們的系統(tǒng)又進(jìn)一步的解耦,表現(xiàn)層真的無(wú)需再關(guān)系DAO層的變化了,一切交給DAO工廠來(lái)解決。
使用過(guò)Spring這樣框架的開(kāi)發(fā)人員都知道,Spring通過(guò)利用IoC來(lái)實(shí)現(xiàn)類(lèi)之間的解耦。其實(shí)在DAO工廠中我們也可以簡(jiǎn)單的借鑒一下IoC的思想,更進(jìn)一步解除類(lèi)之間的耦合。Spring是通過(guò)配置xml文件來(lái)進(jìn)行IoC的,那么我們也可以借助于xml文件來(lái)實(shí)現(xiàn)。比如下面的xml:
<?xml version="1.0"?>
<config>
<daos>
<!-- 組織機(jī)構(gòu)服務(wù)接口實(shí)現(xiàn)類(lèi) -->
<dao id="organizationService"
type="com.baiyyy.oa.services.organization.OrganizationServiceImpl">
</dao>
<!-- 工作流參與者接口 -->
<dao id="participantService"
type="com.baiyyy.workflow.services.impl.ParticipantServiceImpl">
</dao>
<!-- 工作流定義接口 -->
<dao id="processDefinitionService"
type="com.baiyyy.workflow.services.impl.ProcessDefinitionServiceImpl">
</dao>
<!-- 工作流實(shí)例接口 -->
<dao id="processInstanceService"
type="com.baiyyy.workflow.services.impl.ProcessInstanceServiceImpl">
</dao>
</daos>
</config>
這是我設(shè)計(jì)實(shí)現(xiàn)的工作流系統(tǒng)給業(yè)務(wù)系統(tǒng)提供的接口所配置的xml,所有的接口都配置在xml中,我們?cè)趺词褂媚兀课抑徊贿^(guò)是把DAO工廠進(jìn)行進(jìn)一步的改進(jìn),通過(guò)ProcessInstanceService processInstanceService=DaoFactory.getDao(ProcessInstanceService.class,” processInstanceService”);從傳入的參數(shù)我們可以看出,我們清楚的知道要調(diào)用的接口ProcessInstanceService,同時(shí)通過(guò)字符串” processInstanceService”,我們可以解析上面的配置文件,得到具體實(shí)現(xiàn)類(lèi)的路徑,通過(guò)反射得到該實(shí)現(xiàn)類(lèi)的實(shí)例。具體的DAO工廠類(lèi)的實(shí)現(xiàn),朋友們有興趣可以自己去實(shí)現(xiàn),我就不詳細(xì)介紹了。
終于寫(xiě)完了,以上便是對(duì)DAO工廠一些淺顯的理解。現(xiàn)在正在學(xué)習(xí)設(shè)計(jì)模式,以后會(huì)根據(jù)自己的所學(xué)所思,介紹自己對(duì)各個(gè)設(shè)計(jì)模式的理解,希望大家一塊學(xué)習(xí)討論。