Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factory method pattern in java using generics, how to?

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.

like image 645
Jay Avatar asked May 12 '09 23:05

Jay


People also ask

Is generics a design pattern?

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.

What is an example of the Factory Method Pattern used in Java?

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..

How do I set generics 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.


2 Answers

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.

like image 187
Mihai Toader Avatar answered Oct 11 '22 09:10

Mihai Toader


There's a bunch of articles detailing what you need:

  • Generic DAO Pattern With JDK 5.0
  • Generic Data Access Objects (same as above)
  • Don't repeat the DAO (with Spring, but the principles are the same)
  • Java 1.5 Generic DAO (Spring again)

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.

like image 28
javashlook Avatar answered Oct 11 '22 09:10

javashlook