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.
In software engineering world, Factory Design Pattern is used to encapsulate object creation. Generics which is another useful concept, converts runtime typecast errors to compile-time errors. Besides these benefits, Factory Design Pattern and Generics provide a simple approach to manage software problems.
Best Example of Factory method design pattern is valueOf() method which is there in String and wrapper classes like Integer and Boolean and used for type conversion i.e. from converting String to Integer or String to double in java..
Syntax of a Generic SetSet< T > set = new HashSet< T >(); Above syntax is a generalized way to use T to show the generic behavior of a Set which means that T can be replaced with any non-primitive like Integer, String, Double, Character, or any user-defined type.
You should define the factory like that:
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 should return a proper typed DAOFactory.
The factory variable will have the type:
DAOFactory<CustomerDAO> factory = DAOFactory<CustomerDAO>.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.
There's a bunch of articles detailing what you need:
Please note that, unlike your example, there is no reason why the methods of DAOFactory
should not return the actual subclasses (i.e. CustomerDAO getCustomerDAO()
). Furthermore, main benefit of using generic DAOs is having the entity type "genericized", so you don't have to cast from load()/get()/find()
and similar methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With