I have code that looks like follows:
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..
}
}
Now, I do know that this code smells.. for many reasons. However, this code is here too:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html, refer 9.8
What I intend to do is this:
1) Switch my DAOs implementations at runtime based on environment (system properties).
2) Make use of java generics so that I can avoid type casting...
for instance does something like this:
CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();
As opposed to:
CustomerDAO dao = (CustomerDAO) factory.getCustomerDAO();
dao.getCustomer();
Your thoughts and suggestions, please.
解决方案
You should define the factory like that:
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 should return a proper typed DAOFactory.
The factory variable will have the type:
DAOFactory factory = DAOFactory.getInstance(CustomerDAO.class);
and the usage will be properly typed:
CustomerDAO dao = factory.getCustomerDAO();
dao.getCustomer();
the only problem will probably be a cast required inside the getInstance methods.