在JAVA編程的時(shí)候, 有時(shí)候看起來(lái)非常直接的實(shí)現(xiàn)卻非要用設(shè)計(jì)模式轉(zhuǎn)若干個(gè)彎去實(shí)現(xiàn)他, 這似乎顯的很多余,但是采用一些成熟的設(shè)計(jì)模式,會(huì)使程序更加的健壯,松耦合以及好維護(hù)和擴(kuò)展.
實(shí)現(xiàn)DAO 設(shè)計(jì)模式
為DAO實(shí)現(xiàn)工廠類的策略
1 采用工廠方法設(shè)計(jì)模式 如果一個(gè)DAO 工廠只為一個(gè)數(shù)據(jù)庫(kù)的實(shí)現(xiàn),(比如ORACLE)而創(chuàng)建很多的DAO的時(shí)候,實(shí)現(xiàn)該策略時(shí),我們考慮采用工廠方法設(shè)計(jì)模式. 假設(shè)該工廠類創(chuàng)建了CustomerDAO, AccountDAO, OrderDAO 等一些對(duì)象。
2 使用抽象工廠設(shè)計(jì)模式:
如果考慮為三種不同類型的數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)這個(gè)策略,我們可以考慮采用抽象工廠設(shè)計(jì)模式. 假設(shè). 這個(gè)工廠創(chuàng)建了CustomerDAO, AccountDAO, OrderDAO的一系列的DAO, 該策略運(yùn)用了在抽象工廠中產(chǎn)生的工廠類中的工廠方法的實(shí)現(xiàn).
代碼說(shuō)明:
以下代碼舉例說(shuō)明了DAO設(shè)計(jì)模式的具體實(shí)現(xiàn): 我們以使用抽象工廠的設(shè)計(jì)模式來(lái)對(duì)付多種類型數(shù)據(jù)庫(kù)為例,在以下的例子中只具體列出CLOUDSCAPE 數(shù)據(jù)庫(kù)類型的DAO設(shè)計(jì)模式的具體實(shí)現(xiàn),其他類型數(shù)據(jù)庫(kù)DAO設(shè)計(jì)模式的實(shí)現(xiàn)大同小異.
1 // Abstract class DAO Factory public abstract class DAOFactory {
// List of DAO types supported by the factory public static final int CLOUDSCAPE = 1; public static final int ORACLE = 2; public static final int SYBASE = 3; ...
// There will be a method for each DAO that can be // created. The concrete factories will have to // implement these methods. // 所有實(shí)現(xiàn)該抽象工廠的工廠類中必須有的方法,用這些方法來(lái)創(chuàng)建具體的DAO類. public abstract CustomerDAO getCustomerDAO(); public abstract AccountDAO getAccountDAO(); public abstract OrderDAO getOrderDAO();
//該抽象類的靜態(tài)方法,用他來(lái)創(chuàng)建其他具體的DAO工廠類 public static DAOFactory getDAOFactory( int whichFactory) {
switch (whichFactory) { case CLOUDSCAPE: return new CloudscapeDAOFactory(); case ORACLE : return new OracleDAOFactory(); case SYBASE : return new SybaseDAOFactory(); ... default : return null; } } }
2 以下是Cloudscape DAO FACTORY 類的實(shí)現(xiàn),在他里面實(shí)現(xiàn)了該類型數(shù)據(jù)庫(kù)的連接,以及實(shí)現(xiàn)了他所繼承的抽象工廠類中所必須實(shí)現(xiàn)的那些方法,在這些方法中創(chuàng)建具體的DAO對(duì)象.
// Cloudscape concrete DAO Factory implementation import java.sql.*;
public class CloudscapeDAOFactory extends DAOFactory { public static final String DRIVER= "COM.cloudscape.core.RmiJdbcDriver"; public static final String DBURL= "jdbc:cloudscape:rmi://localhost:1099/CoreJ2EEDB";
// method to create Cloudscape connections //建立Cloudscape 連接 public static Connection createConnection() { // Use DRIVER and DBURL to create a connection // Recommend connection pool implementation/usage } //創(chuàng)建 CustomerDAO 對(duì)象 當(dāng)然返回的是一個(gè)該類實(shí)現(xiàn)的接口,他的好處就是實(shí)現(xiàn)了實(shí)現(xiàn)細(xì)節(jié)的隱蔽. public CustomerDAO getCustomerDAO() { // CloudscapeCustomerDAO implements CustomerDAO return new CloudscapeCustomerDAO(); } //創(chuàng)建 AccountDAO 對(duì)象 當(dāng)然返回的是一個(gè)該類實(shí)現(xiàn)的接口,他的好處就是實(shí)現(xiàn)了實(shí)現(xiàn)細(xì)節(jié)的隱蔽. public AccountDAO getAccountDAO() { // CloudscapeAccountDAO implements AccountDAO return new CloudscapeAccountDAO(); } //創(chuàng)建 OrderDAO 對(duì)象 當(dāng)然返回的是一個(gè)該類實(shí)現(xiàn)的接口,他的好處就是實(shí)現(xiàn)了實(shí)現(xiàn)細(xì)節(jié)的隱蔽.
public OrderDAO getOrderDAO() { // CloudscapeOrderDAO implements OrderDAO return new CloudscapeOrderDAO(); } ... }
3 以下代碼就是具體DAO類實(shí)現(xiàn)的接口也就是CloudscapeCustomerDAO()實(shí)現(xiàn)的接口: CustomerDAO .在該接口中定義了所有的業(yè)務(wù)方法.
// Interface that all CustomerDAOs must support public interface CustomerDAO { public int insertCustomer(...); public boolean deleteCustomer(...); public Customer findCustomer(...); public boolean updateCustomer(...); public RowSet selectCustomersRS(...); public Collection selectCustomersTO(...); ... }
4 以下CloudscapeCustomerDAO類實(shí)現(xiàn)的具體業(yè)務(wù)細(xì)節(jié)和數(shù)據(jù)操作細(xì)節(jié), 他是要向客戶數(shù)據(jù)端隱蔽的.
import java.sql.*; public class CloudscapeCustomerDAO implements CustomerDAO { public CloudscapeCustomerDAO() { // initialization } // The following methods can use // CloudscapeDAOFactory.createConnection() // to get a connection as required public int insertCustomer(...) { // Implement insert customer here. // Return newly created customer number // or a -1 on error } public boolean deleteCustomer(...) { // Implement delete customer here // Return true on success, false on failure } public Customer findCustomer(...) { // Implement find a customer here using supplied // argument values as search criteria // Return a Transfer Object if found, // return null on error or if not found } public boolean updateCustomer(...) { // implement update record here using data // from the customerData Transfer Object // Return true on success, false on failure or // error } public RowSet selectCustomersRS(...) { // implement search customers here using the // supplied criteria. // Return a RowSet. } public Collection selectCustomersTO(...) { // implement search customers here using the // supplied criteria. // Alternatively, implement to return a Collection // of Transfer Objects. } ... }
5 下面的代碼是數(shù)據(jù)客戶端向DAO中傳輸數(shù)據(jù)的, 他其實(shí)就是一個(gè)JAVABEAN;
public class Customer implements java.io.Serializable { // member variables int CustomerNumber; String name; String streetAddress; String city; ...
// getter and setter methods... ... }
6 最后就是客戶數(shù)據(jù)端對(duì)這個(gè)設(shè)計(jì)的應(yīng)用: ... // create the required DAO Factory DAOFactory cloudscapeFactory = DAOFactory.getDAOFactory(DAOFactory.DAOCLOUDSCAPE); // Create a DAO CustomerDAO custDAO = cloudscapeFactory.getCustomerDAO(); // create a new customer int newCustNo = custDAO.insertCustomer(...); // Find a customer object. Get the Transfer Object. Customer cust = custDAO.findCustomer(...); // modify the values in the Transfer Object. cust.setAddress(...); cust.setEmail(...); // update the customer object using the DAO custDAO.updateCustomer(cust); // delete a customer object custDAO.deleteCustomer(...); // select all customers in the same city Customer criteria=new Customer(); criteria.setCity("New York"); Collection customersList = custDAO.selectCustomersTO(criteria); // returns customersList - collection of Customer // Transfer Objects. iterate through this collection to // get values.
言而簡(jiǎn)之,以下6步完成該模式的實(shí)現(xiàn):
1 創(chuàng)建一個(gè)抽象工廠類,他包含兩個(gè)重要的部分: 第一部分是 一些抽象方法,這些方法是所有實(shí)現(xiàn)該抽象工廠的具體工廠類所必須實(shí)現(xiàn)的. 第二部分 就是一個(gè)靜態(tài)方法,該方法來(lái)創(chuàng)建一個(gè)具體類型數(shù)據(jù)源的工廠對(duì)象,比如文中的CloudscapeDAOFactory().
2 然后,分別創(chuàng)建各個(gè)類型數(shù)據(jù)源的工廠類,(本文以CloudscapeDAOFactory為例).在這個(gè)工廠類中里面也有兩個(gè)重要組成部分: 第一部分就是實(shí)現(xiàn)在他繼承的那個(gè)抽象工廠類中的左右抽象方法,在該方法中創(chuàng)建具體的DAO對(duì)象(這些對(duì)象的類在第4不具體定義實(shí)現(xiàn)),本文中三個(gè)方法分別創(chuàng)建了3個(gè)具體的DAO對(duì)象,當(dāng)然為了實(shí)現(xiàn)細(xì)節(jié)的隱蔽,這些方法返回的是這些具體DAO類門(mén)實(shí)現(xiàn)的接口(這些接口在第3步實(shí)現(xiàn)).
3 定義具體DAO類的接口,并在接口中定義所有的業(yè)務(wù)方法,和數(shù)據(jù)操作方法.
4 定義具體的DAO類,在這個(gè)類中才是實(shí)際的業(yè)務(wù)方法,和數(shù)據(jù)的操作的實(shí)現(xiàn).
5 定義數(shù)據(jù)傳輸對(duì)象,他是用來(lái)在客戶端和DAO之間傳遞數(shù)據(jù)的,他其實(shí)就是一個(gè)JAVABEAN.
6 完成以上5步之后我們就可以在數(shù)據(jù)客戶端使用以上由DAO設(shè)計(jì)模式定義好的各個(gè)類了(見(jiàn)最后一個(gè)代碼例子塊).
以上6步大家在編程的時(shí)需具體體會(huì),一般來(lái)說(shuō),數(shù)據(jù)庫(kù)中的一個(gè)表就可以對(duì)應(yīng)一個(gè)數(shù)據(jù)傳遞類也就是在第4步中定義的那個(gè)類,類中的屬性就是表中的字段,然后加上相應(yīng)的GET,SET 方法. 然后再按模式和以上步驟來(lái)定義具體的類.
本文譯自:http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
jegg
JAVA-J2EE-DESIGH PATTERN
共享就是力量!
|