[英]Factory method pattern in java using generics, how to?
我的代码如下所示:
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)使用java泛型,以便我可以避免类型转换...例如,做这样的事情:
CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();
相反:
CustomerDAO dao = (CustomerDAO) factory.getCustomerDAO();
dao.getCustomer();
请你的意见和建议。
您应该像这样定义工厂:
public abstract class DAOFactory<DAO extends BaseDAO> {
public DAO getCustomerDAO();
public static <DAO extends BaseDAO> DAOFactory<DAO> getInstance(Class<DAO> 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<CustomerDAO> factory = DAOFactory<CustomerDAO>.getInstance(CustomerDAO.class);
并且将正确输入用法:
CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();
唯一的问题可能是getInstance方法中需要的强制转换。
有一堆文章详细说明了你的需求:
请注意,与您的示例不同, DAOFactory
的方法没有理由不返回实际的子类(即CustomerDAO getCustomerDAO()
)。 此外,使用通用DAO的主要好处是使实体类型“通用化”,因此您不必从load()/get()/find()
和类似方法进行转换。
您的示例并未证明需要BaseDAO
,并且没有理由不应声明DAOFactory.getCustomerDAO()
返回CustomerDAO
。 所以,我并不认为那里需要仿制药。 但是,请考虑以下事项:
interface DataAccess<T> {
void store(T entity);
T lookup(Serialiable identifier);
void delete(Serializable identifier);
Collection<? extends T> find(Criteria query);
}
abstract class DataAccessFactory {
abstract DataAccess<T> getDataAccess(Class<T> clz);
static DataAccessFactory getInstance() {
...
}
}
我在几个项目中使用了类似这种方法的东西,编写一个适用于模型中每个实体的DAO非常好。 弱点是“发现者”方法。 有一些巧妙的方法,JPA即将开展的工作是标准化“Criteria”API,但是现在通常最容易公开底层持久性机制的标准。
当我使用工厂时,我通常使用instanceof来确定对象的真实类型。 例如:
CustomerDAO dao;
if (factory.getCustomerDAO() instanceof CustomerDAO) {
dao = factory.getCustomerDAO();
}
dao.getCustomer();
这对我来说似乎更干净,特别是如果factory.getCustomerDAO()没有返回任何接近CustomerDAO的东西(由于实现的变化)。
只是我的两分钱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.