java中使用generics的工厂方法模式,如何?

我的代码如下所示:

public interface BaseDAO{ // marker interface } public interface CustomerDAO extends BaseDAO{ public void createCustomer(); public void deleteCustomer(); public Customer getCustomer(int id); // etc } public abstract class DAOFactory { public BaseDAO getCustomerDAO(); public static DAOFactory getInstance(){ if(system.getProperty("allowtest").equals("yes")) { return new TestDAOFactory(); } else return new ProdDAOFactory(); } public class TestDAOFactory extends DAOFactory{ public BaseDAO getCustomerDAO() { return new TestCustomerDAO(); // this is a concrete implementation //that extends CustomerDAO //and this implementation has dummy code on methods } public class ProdDAOFactory extends DAOFactory { public BaseDAO getCustomerDAO() { return new ProdCustomerDAO(); // this implementation would have // code that would connect to the database and do some stuff.. } } 

现在,我知道这段代码闻起来有很多原因。 但是,此代码也在这里: http : //java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html ,请参阅9.8

我打算这样做:1)根据环境(系统属性)在运行时切换我的DAO实现。 2)使用javagenerics,以便我可以避免类型转换…例如,做这样的事情:

 CustomerDAO dao = factory.getCustomerDAO(); dao.getCustomer(); 

相反:

 CustomerDAO dao = (CustomerDAO) factory.getCustomerDAO(); dao.getCustomer(); 

请你的意见和建议。

您应该像这样定义工厂:

 public abstract class DAOFactory { public DAO getCustomerDAO(); public static  DAOFactory getInstance(Class typeToken){ // instantiate the the proper factory by using the typeToken. if(system.getProperty("allowtest").equals("yes")) { return new TestDAOFactory(); } else return new ProdDAOFactory(); } 

getInstance应该返回一个正确的类型DAOFactory。

工厂变量将具有以下类型:

 DAOFactory factory = DAOFactory.getInstance(CustomerDAO.class); 

并且将正确输入用法:

 CustomerDAO dao = factory.getCustomerDAO(); dao.getCustomer(); 

唯一的问题可能是getInstance方法中需要的强制转换。

有一堆文章详细说明了你的需求:

  • JDK 5.0的通用DAO模式
  • 通用数据访问对象 (与上面相同)
  • 不要重复DAO (使用Spring,但原则是相同的)
  • Java 1.5 Generic DAO (Spring再次出现)

请注意,与您的示例不同, DAOFactory的方法没有理由不返回实际的子类(即CustomerDAO getCustomerDAO() )。 此外,使用通用DAO的主要好处是使实体类型“泛化”,因此您不必从load()/get()/find()和类似方法进行转换。

您的示例并未certificate需要BaseDAO ,并且没有理由不应声明DAOFactory.getCustomerDAO()返回CustomerDAO 。 所以,我并不认为那里需要仿制药。 但是,请考虑以下事项:

 interface DataAccess { void store(T entity); T lookup(Serialiable identifier); void delete(Serializable identifier); Collection find(Criteria query); } abstract class DataAccessFactory { abstract DataAccess getDataAccess(Class clz); static DataAccessFactory getInstance() { ... } } 

我在几个项目中使用了类似这种方法的东西,编写一个适用于模型中每个实体的DAO非常好。 缺点是“取景器”方法。 有一些巧妙的方法,JPA即将开展的工作是标准化“Criteria”API,但目前通常最容易公开底层持久性机制的标准。

当我使用工厂时,我通常使用instanceof来确定对象的真实类型。 例如:

 CustomerDAO dao; if (factory.getCustomerDAO() instanceof CustomerDAO) { dao = factory.getCustomerDAO(); } dao.getCustomer(); 

这对我来说似乎更干净,特别是如果factory.getCustomerDAO()没有返回任何接近CustomerDAO的东西(由于实现的变化)。

只是我的两分钱。