国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

工廠設(shè)計(jì)模式的研究與應(yīng)用

2017-07-12 08:07:38葛萌歐陽(yáng)宏基

葛萌+歐陽(yáng)宏基

摘要:為了提高傳統(tǒng)JDBC框架的復(fù)用性,分析了工廠設(shè)計(jì)模式的三種具體形式:簡(jiǎn)單工廠、工廠方法和抽象工廠。闡述了三者之間的優(yōu)缺點(diǎn),從進(jìn)化和退化兩個(gè)方面分析了三者之間的轉(zhuǎn)換關(guān)系。將工廠設(shè)計(jì)模式與JDBC相結(jié)合,設(shè)計(jì)了一個(gè)數(shù)據(jù)持久層模型,給出了該模型的設(shè)計(jì)思想與若干核心代碼。通過(guò)相關(guān)分析與測(cè)試表明:將工廠設(shè)計(jì)模式應(yīng)用到持久層的設(shè)計(jì)中能夠減少代碼的冗余度、提高復(fù)用性和擴(kuò)展性。

關(guān)鍵詞:簡(jiǎn)單工廠;工廠方法;抽象工廠;JDBC

Abstract:In order to improve the reusability of the traditional JDBC framework,this paper analyzes three concrete forms of the factory design pattern,which are simple factory, factory method and abstract factory. expounds the advantages and disadvantages of the three,the transformation relationship between the three is analyzed from two aspects of evolution and degradation.designs a data persistence layer model with combining factory design pattern and JDBC,gives the design idea and some core codes of the model.Through the correlation analysis and test, it is indicated that the factory design pattern can be applied to the design of persistent layer, which can reduce the redundancy of the code, improve the reusability and expansibility.

Key words:simple factory;factory method;abstract factory;JDBC

0. 引言

工廠設(shè)計(jì)模式屬于創(chuàng)建型模式中使用最為頻繁的一種,它的主要思想是將對(duì)象的創(chuàng)建封裝到一種稱為“工廠”的類中,從調(diào)用方角度來(lái)看,需要“產(chǎn)品”時(shí),不需要親自new出來(lái),通過(guò)調(diào)用工廠對(duì)象的方法就可以得到對(duì)象。因此,合理的使用工廠設(shè)計(jì)模式能夠?qū)?duì)象的創(chuàng)建和使用相分離,從而減少類之間的耦合度,提高復(fù)用性。本文首先介紹了工廠設(shè)計(jì)模式中的三種具體形式:簡(jiǎn)單工廠模式、工廠方法模式和抽象工廠模式,詳細(xì)描述了每種形式的組成以及各角色在模式中承擔(dān)的功能,從進(jìn)化和退化兩個(gè)方面分析了它們?nèi)咧g的轉(zhuǎn)換關(guān)系。最后,以JDBC作為Java EE應(yīng)用持久層解決方案的背景下,將工廠模式的三種具體形式應(yīng)用到持久層的設(shè)計(jì)過(guò)程中,提出了一個(gè)數(shù)據(jù)持久層模型,對(duì)該模型的設(shè)計(jì)過(guò)程進(jìn)行了分析,通過(guò)相關(guān)測(cè)試證明了它的有效性。

1.工廠設(shè)計(jì)模式分析

1.1簡(jiǎn)單工廠模式

簡(jiǎn)單工廠模式包含三個(gè)角色[1]:抽象產(chǎn)品、具體產(chǎn)品和工廠。抽象產(chǎn)品角色是工廠所創(chuàng)建的所有對(duì)象的共同父類,描述了所有產(chǎn)品的公共接口。具體產(chǎn)品是該模式的創(chuàng)建目標(biāo),所有創(chuàng)建的對(duì)象都充當(dāng)這個(gè)角色的某個(gè)具體類的實(shí)例。工廠角色對(duì)外提供一個(gè)靜態(tài)的工廠方法用來(lái)創(chuàng)建所有的具體產(chǎn)品,通過(guò)參數(shù)動(dòng)態(tài)決定所創(chuàng)建產(chǎn)品的類型,方法內(nèi)部針對(duì)參數(shù)形成判斷邏輯。當(dāng)產(chǎn)品類型發(fā)生變化時(shí)會(huì)導(dǎo)致判斷邏輯的變化,所以簡(jiǎn)單工廠模式不滿足“開(kāi)閉原則”。

1.2 工廠方法模式

工廠方法模式[2]一共包含4個(gè)角色:抽象產(chǎn)品、具體產(chǎn)品、抽象工廠和具體工廠。抽象產(chǎn)品是產(chǎn)品對(duì)象的共同父類或接口。具體產(chǎn)品由某種類型的具體工廠所創(chuàng)建。抽象工廠用來(lái)聲明工廠方法并返回產(chǎn)品。具體工廠用來(lái)創(chuàng)建一個(gè)具體的產(chǎn)品類對(duì)象,其中包含了與應(yīng)用程序密切相關(guān)的邏輯。具體工廠與具體產(chǎn)品一一對(duì)應(yīng)。相對(duì)于簡(jiǎn)單工廠,工廠方法在工廠這一側(cè)進(jìn)行了抽象,將具體產(chǎn)品的創(chuàng)建延遲到工廠子類中進(jìn)行。如果系統(tǒng)中引入了新的產(chǎn)品,那么只需要?jiǎng)?chuàng)建新的產(chǎn)品和新的工廠即可,系統(tǒng)中原來(lái)的產(chǎn)品和工廠類不需要修改,所以工廠方法很好的滿足了“開(kāi)閉原則”。

1.3 抽象工廠模式

工廠方法模式中只能生產(chǎn)一種類型的產(chǎn)品,當(dāng)產(chǎn)品種類多于一種時(shí),工廠方法模式就不滿足“開(kāi)閉原則”,此時(shí)只能使用抽象工廠模式。理解抽象工廠模式首先要明確兩個(gè)概念:產(chǎn)品等級(jí)結(jié)構(gòu)和產(chǎn)品族[3-4]。前者表示產(chǎn)品一側(cè)的泛化關(guān)系,后者表示同一個(gè)工廠所生產(chǎn)的、位于不同等級(jí)結(jié)構(gòu)中的一組不同種類的產(chǎn)品。抽象工廠定義一組生成抽象產(chǎn)品的方法,每個(gè)方法對(duì)應(yīng)一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)。具體工廠生產(chǎn)一組具體產(chǎn)品形成一個(gè)產(chǎn)品族,每一個(gè)產(chǎn)品都位于某個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)中。抽象產(chǎn)品用于定義產(chǎn)品的抽象業(yè)務(wù)。具體工廠生產(chǎn)具體產(chǎn)品對(duì)象。

1.4 三者的優(yōu)缺點(diǎn)及轉(zhuǎn)換

工廠設(shè)計(jì)模式的核心在于將對(duì)象的創(chuàng)建和對(duì)象本身業(yè)務(wù)處理相分離,降低系統(tǒng)的耦合度,使兩者的修改變得簡(jiǎn)單。簡(jiǎn)單工廠模式將所有產(chǎn)品的創(chuàng)建過(guò)程封裝到工廠類的靜態(tài)方法中,通過(guò)傳入正確的參數(shù)即可獲得所需對(duì)象。但是工廠類的任務(wù)相對(duì)繁重,尤其是在產(chǎn)品類過(guò)多的情況下,工廠類會(huì)有繁瑣的判斷邏輯;而且增加新產(chǎn)品的同時(shí)需要修改判斷邏輯。

工廠方法模式在工廠一側(cè)引入了泛化關(guān)系,它的實(shí)現(xiàn)依賴于工廠角色與產(chǎn)品角色的多態(tài)性。把原來(lái)集中創(chuàng)建產(chǎn)品對(duì)象的方式改為分散式創(chuàng)建,每一個(gè)具體工廠創(chuàng)建每一種具體產(chǎn)品。如果有新產(chǎn)品的加入,只需增加具體產(chǎn)品類和對(duì)應(yīng)的具體工廠類即可,原來(lái)的代碼無(wú)需更改。

但是工廠方法模式只能創(chuàng)建類型單一的產(chǎn)品,當(dāng)產(chǎn)品類型增多時(shí),系統(tǒng)中類的個(gè)數(shù)成對(duì)增加,提高了系統(tǒng)的復(fù)雜度和編譯開(kāi)銷。

抽象工廠模式解決了工廠方法模式所創(chuàng)建產(chǎn)品種類單一的問(wèn)題,它提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無(wú)須指定它們具體的類[5-6]。產(chǎn)品等級(jí)結(jié)構(gòu)決定了產(chǎn)品種類的個(gè)數(shù),產(chǎn)品族決定了具體工廠的個(gè)數(shù)。從產(chǎn)品族的角度而言,增加新的具體工廠時(shí)無(wú)須修改原有代碼,滿足開(kāi)閉原則;從產(chǎn)品等級(jí)結(jié)構(gòu)的角度而言,增加新的產(chǎn)品類型時(shí)需要修改其中的抽象工廠角色代碼,同時(shí)還要修改各個(gè)具體的工廠類。所以,抽象工廠模式對(duì)于開(kāi)閉原則具有半傾斜性[7]。它們?nèi)叩膬?yōu)缺點(diǎn)及轉(zhuǎn)換關(guān)系見(jiàn)表1。

2. 工廠設(shè)計(jì)模式在Java EE持久層的應(yīng)用

Java EE的持久層用來(lái)封裝數(shù)據(jù)持久化邏輯并為業(yè)務(wù)層提供訪問(wèn)數(shù)據(jù)源的接口,提供諸如數(shù)據(jù)源連接、查詢、存儲(chǔ)過(guò)程、數(shù)據(jù)格式修正和錯(cuò)誤處理等功能[8]。其目的是為了解耦合業(yè)務(wù)處理和數(shù)據(jù)存取,為企業(yè)應(yīng)用形成一個(gè)高效、穩(wěn)定的數(shù)據(jù)訪問(wèn)環(huán)境。由于關(guān)系型數(shù)據(jù)庫(kù)在數(shù)據(jù)存儲(chǔ)方面仍然占據(jù)主導(dǎo)地位,所以圍繞SQL產(chǎn)生出了很多數(shù)據(jù)持久層解決方案:包括JDBC、全自動(dòng)化的ORM(例如Hibernate)、半自動(dòng)化的ORM(例如MyBatis)以及JDO等。其中JDBC是最原生態(tài)的SQL解決方案,具有執(zhí)行效率最高、易于掌握等特點(diǎn),但也有復(fù)用率低、不易擴(kuò)展等缺點(diǎn)。本節(jié)主要討論如何將工廠設(shè)計(jì)模式應(yīng)用到JDBC中并設(shè)計(jì)一個(gè)數(shù)據(jù)持久層模型。

2.1 抽象工廠模式的應(yīng)用

結(jié)合應(yīng)用背景,分析出產(chǎn)品等級(jí)結(jié)構(gòu)和產(chǎn)品族是應(yīng)用抽象工廠模式的關(guān)鍵。為了隔離業(yè)務(wù)邏輯與持久化邏輯,Java EE規(guī)范推薦采用DAO模式。通常的做法是在DAO接口中定義相關(guān)的持久化方法,DAO實(shí)現(xiàn)類中應(yīng)用某種具體的持久化技術(shù)來(lái)完成持久化方法[9]。由于一個(gè)系統(tǒng)中存在多個(gè)不同的實(shí)體對(duì)象,它們所對(duì)應(yīng)的DAO可以看作產(chǎn)品等級(jí)結(jié)構(gòu);由于不同數(shù)據(jù)庫(kù)具有SQL“方言”,在執(zhí)行相同的持久化邏輯時(shí)SQL語(yǔ)句會(huì)有所差別,因此在某個(gè)特定數(shù)據(jù)庫(kù)下的各種DAO的實(shí)現(xiàn)類可以看作一個(gè)產(chǎn)品族。業(yè)務(wù)層要對(duì)實(shí)體對(duì)象進(jìn)行持久化操作必須通過(guò)工廠獲取對(duì)應(yīng)的DAO對(duì)象。以MySQL數(shù)據(jù)庫(kù)為例,部分角色的代碼如下:

public interface DAOFactory

{ //定義系統(tǒng)中所有實(shí)體對(duì)象的DAO

UserDAO createUserDAO();

DepartmentDAO createDepartmentDAO();

……………………

}

每個(gè)具體的數(shù)據(jù)庫(kù)對(duì)應(yīng)一個(gè)具體工廠,代碼如下:

public class MySQLDAOFactory implements DAOFactory

{

public UserDAO createUserDAO() {

return new MySQLUserDAOImp();

}

public DepartmentDAO createDepartmentDAO() {

return new MySQLDepartmentDAOImp();

}

……………………………………………

}

2.2 工廠方法模式的應(yīng)用

JDBC的操作一般包括4個(gè)步驟[10]:(1)加載驅(qū)動(dòng);(2)獲取Connection;(3)創(chuàng)建相關(guān)Statement對(duì)象并執(zhí)行SQL語(yǔ)句;(4)釋放資源。為了減少代碼的冗余度,定義抽象類JDBCUtil用來(lái)執(zhí)行步驟(1)、(2)和(4),將該類對(duì)象看作工廠模式中的唯一抽象產(chǎn)品,定義JDBCUtilFactory當(dāng)作工廠方法模式中的抽象工廠,每種具體數(shù)據(jù)庫(kù)對(duì)應(yīng)一個(gè)JDBCUtil和JDBCUtilFactory的實(shí)現(xiàn)類,分別當(dāng)作具體產(chǎn)品和具體工廠。根據(jù)上述分析,具體產(chǎn)品角色代碼如下:

public class MySQLJDBCUtil extends JDBCUtil

{ static{

Class.forName("com.mysql.jdbc.Driver");

……………. }

public Connection getConnection() throws SQLException{

return DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName",”root”,”root”);

}

具體工廠角色代碼如下:

public class MySQLJDBCUtilFactory implements JDBCUtilFactory

{

public JDBCUtil createJDBCUtil() {

return new MySQLJDBCUtil();

}

}

2.3 簡(jiǎn)單工廠模式的應(yīng)用

通過(guò)對(duì)2.3節(jié)的代碼分析可以看出:不同數(shù)據(jù)庫(kù)所對(duì)應(yīng)的具體產(chǎn)品和具體工廠的代碼結(jié)構(gòu)相同,不同之處在于JDBC驅(qū)動(dòng)的名稱和創(chuàng)建Connection對(duì)象時(shí)傳入的URL參數(shù)。為了進(jìn)一步減少冗余度,將這些參數(shù)定義到配置文件中,在程序運(yùn)行時(shí)通過(guò)讀取配置文件動(dòng)態(tài)傳入。這樣的話,對(duì)于工廠方法模式而言,產(chǎn)品和工廠就不存在抽象層,從而退化成為簡(jiǎn)單工廠模式。

首先,定義讀取配置文件的類-JDBCConfigReader,其中關(guān)聯(lián)一個(gè)Properties對(duì)象,該對(duì)象用于讀取properties類型的配置文件。properties類型的配置文件具有易于理解、讀寫簡(jiǎn)單等特點(diǎn),以鍵值對(duì)形式存放數(shù)據(jù)。由于配置文件中的內(nèi)容只需讀取一次,放入內(nèi)存供其它對(duì)象使用,所以JDBCConfigReader采用單例模式封裝。

然后,定義簡(jiǎn)單工廠模式中的產(chǎn)品和工廠類。產(chǎn)品類的代碼如下:

public class JDBCUtil

{ static{

Class.forName(JDBCConfigReader.getInstance().getProperties().getProperty("DriverClass");

}

public Connection getConnection() throws SQLException{

String url=JDBCConfigReader.getInstance().getProperties().getProperty("DBURL");

String userName=JDBCConfigReader.getInstance().getProperties().getProperty("DBUserName");

String password=JDBCConfigReader.getInstance().getProperties().getProperty("DBPassword");

return DriverManager.getConnection(url,userName,password);

} }

工廠類的代碼如下:

public class JDBCUtilFactory

{

public static JDBCUtil createJDBCUtil(){

return new JDBCUtil(); }

}

與2.3節(jié)的代碼對(duì)比可以看出:將不同數(shù)據(jù)庫(kù)的相關(guān)JDBC參數(shù)存儲(chǔ)到配置文件后,工廠方法模式退化成了簡(jiǎn)單工廠模式,產(chǎn)品和工廠兩個(gè)角色都變成了一個(gè)對(duì)象,不但減少了產(chǎn)品類和具體工廠類的個(gè)數(shù),而且工廠類在創(chuàng)建產(chǎn)品對(duì)象時(shí)也避免了邏輯判斷。

2.4 業(yè)務(wù)層對(duì)持久層的調(diào)用

假定當(dāng)前系統(tǒng)中的一個(gè)實(shí)體對(duì)象是User,它對(duì)應(yīng)的DAO實(shí)現(xiàn)類的代碼如下:

public class MySQLUserDAOImp implements UserDAO

{

//通過(guò)JDBCUtil工廠得到JDBCUtil產(chǎn)品

private JDBCUtil jdbcUtil=new JDBCUtilFactory().createJDBCUtil();

//相關(guān)實(shí)體類的持久化方法

public boolean addUser(User user)

{

Connection con=jdbcUtil.getConnection();

………………………

}

}

將當(dāng)前實(shí)際使用的數(shù)據(jù)庫(kù)所對(duì)應(yīng)的DAO工廠類信息寫到配置文件中,將抽象工廠模式中的具體工廠當(dāng)作簡(jiǎn)單工廠模式中的具體產(chǎn)品,通過(guò)反射機(jī)制創(chuàng)建出具體的DAO工廠,如下代碼所示:

public class DAOFactory

{

public static DAOFactory getDAOFactory()

{ DAOFactory factory=null;

String DAOFactoryName=JDBCConfigReader.getInstance().getProperties().getProperty("DAOFactory"); factory=(DAOFactory)Class.forName(DAOFactoryName).newInstance(); }

return factory;

} }

當(dāng)業(yè)務(wù)層要獲取相關(guān)實(shí)體的DAO對(duì)象時(shí),執(zhí)行下面代碼:

DAOFactory factory=DAOFactoryConfig.getDAOFactory();

UserDAO userDAO=factory.getUserDAO();

通過(guò)上述分析可以看出:業(yè)務(wù)層對(duì)于持久層方法的調(diào)用,首先通過(guò)簡(jiǎn)單工廠讀取配置文件得到抽象工廠模式的具體DAO工廠,然后將具體DAO工廠生產(chǎn)的DAO產(chǎn)品賦值給抽象DAO,通過(guò)抽象DAO調(diào)用相關(guān)實(shí)體的持久化方法。這時(shí)與業(yè)務(wù)層進(jìn)行通信的只是抽象DAO工廠和抽象DAO產(chǎn)品。業(yè)務(wù)層不需要知道當(dāng)前DAO對(duì)象由哪個(gè)具體的工廠創(chuàng)建。因此,不論使用哪種數(shù)據(jù)庫(kù),對(duì)業(yè)務(wù)層的調(diào)用來(lái)說(shuō)沒(méi)有任何影響,滿足持久層支持多數(shù)據(jù)庫(kù)的要求。綜合上述,本文設(shè)計(jì)的持久層模型如圖1所示。

2.5 工廠設(shè)計(jì)模式應(yīng)用評(píng)價(jià)

將本文設(shè)計(jì)的數(shù)據(jù)持久層模型與傳統(tǒng)JDBC進(jìn)行比較,觀測(cè)點(diǎn)為執(zhí)行效率與復(fù)用率。其中不包括DAO,因?yàn)镈AO的代碼與具體業(yè)務(wù)相關(guān),測(cè)試工具為JUnit和JDK的Executor并發(fā)框架。在單機(jī)環(huán)境下采用單線程和多線程(并發(fā)量為50)兩種形式,執(zhí)行時(shí)間為多次執(zhí)行的平均值,測(cè)試結(jié)果見(jiàn)表2和表3。可以看出工廠設(shè)計(jì)模式的應(yīng)用提高了代碼的復(fù)用率,尤其是簡(jiǎn)單工廠模式+反射讀取配置文件來(lái)創(chuàng)建對(duì)象的方式,完全可以復(fù)用。在執(zhí)行效率方面,本文設(shè)計(jì)的持久層模型與傳統(tǒng)JDBC的執(zhí)行開(kāi)銷差別很小。在多線程情況下,本文模型效率略有提高。這表明工廠設(shè)計(jì)模式在提高復(fù)用率的情況下,雖然增了的類與對(duì)象的調(diào)用開(kāi)銷,但對(duì)性能的影響可以忽略,因此本模型是有效、可靠的。

3. 結(jié)論

本文對(duì)工廠設(shè)計(jì)模式進(jìn)行了研究,分析了他們的優(yōu)缺點(diǎn)和轉(zhuǎn)換關(guān)系。將工廠設(shè)計(jì)模式與JDBC相結(jié)合,提出了一種數(shù)據(jù)持久化模型。通過(guò)實(shí)際測(cè)試表明工廠設(shè)計(jì)模式能夠很好的將對(duì)象的創(chuàng)建和使用相分離,向調(diào)用方屏蔽對(duì)象的創(chuàng)建過(guò)程,在不增加過(guò)多額外開(kāi)銷的情況下,提高了代碼的復(fù)用率、擴(kuò)展性和維護(hù)性。為開(kāi)發(fā)人員在設(shè)計(jì)過(guò)程中合理使用工廠設(shè)計(jì)模式提供了一定的參考。

參考文獻(xiàn)

[1]薛桂香,任女爾,閆世峰,林濤. 基于簡(jiǎn)單工廠模式的SSH+ExtJs架構(gòu)泛型化研究[J].河北工業(yè)大學(xué)學(xué)報(bào),2015,44(3):65-69.

[2]華銓平,龐倩超,謝穎.抽象工廠設(shè)計(jì)模式在3 層結(jié)構(gòu)開(kāi)發(fā)中的應(yīng)用[J].大慶石油學(xué)院學(xué)報(bào),2009,33(3):112-115.

[3]郭永平,劉淑娟.工廠方法模式在軟件開(kāi)發(fā)中的應(yīng)用—以監(jiān)控?cái)?shù)據(jù)接收服務(wù)程序?yàn)槔齕J].寶雞文理學(xué)院學(xué)報(bào)(自然科學(xué)版),2015,35(4):58-62.

[4]歐建斌.工廠設(shè)計(jì)的模式研究[J].微型電腦應(yīng)用,2010,26(12):15-17.

[5]歐陽(yáng)宏基,葛萌,陳偉.一種改進(jìn)的建造者設(shè)計(jì)模式[J].咸陽(yáng)師范學(xué)院學(xué)報(bào),2014,29(6):43-46.

[6]程裕強(qiáng).抽象工廠模式探討[J].玉林師范學(xué)院學(xué)報(bào),2014,35(2):82-86.

[7]劉偉.設(shè)計(jì)模式[M].北京:清華大學(xué)出版社,2011:92-103.

[8]尚鮮連.設(shè)計(jì)模式在數(shù)據(jù)持久層設(shè)計(jì)中的應(yīng)用[J].重慶科技學(xué)院學(xué)報(bào)(自然科學(xué)版),2008,10(6):18-111.

[9]周寧,苗放,周麗.在DAO 模式中實(shí)現(xiàn)數(shù)據(jù)庫(kù)間差異消除及數(shù)據(jù)庫(kù)操作的移植[J].計(jì)算機(jī)工程與科學(xué),2006,28(10):111-113.

[10]歐陽(yáng)宏基,葛萌,趙薔.基于JDBC與設(shè)計(jì)模式的數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn)方法[J].計(jì)算機(jī)技術(shù)與發(fā)展,2011,21(1):84-87.

洞口县| 封丘县| 安徽省| 吉水县| 红安县| 长乐市| 阜城县| 无棣县| 金乡县| 绥化市| 仁布县| 永安市| 泾阳县| 定襄县| 西平县| 攀枝花市| 嘉峪关市| 芦山县| 大埔区| 乡宁县| 隆化县| 辽阳县| 长兴县| 商城县| 瑞昌市| 榆社县| 乐东| 武鸣县| 永春县| 北川| 和林格尔县| 鞍山市| 弥勒县| 大连市| 绥江县| 茌平县| 广南县| 札达县| 牟定县| 蓬安县| 剑川县|