• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help me see if possible Generic DAO Factory

Khor Yong Hao
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What I need to make in Dao Factory is something like this

I have DaoFactory class, BaseDao (Parent Dao), and then where UserDao, ProductDao will extends BaseDao

In my use case, I would like to



DaoFactory.getDao("user") will implicitly return UserDao instance.

But inside this getDao implementation, it is not hardcoding the UserDao and ProductDao instance inside.
Means, when the developer add new Dao class such as MemberDao,
then he needs not to change DaoFactory class but just using DaoFactory.getDao("member") to return his MemberDao

I am guessing using this type of method:

However, what the result I had got is:

when I DaoFactory.getDao("product")

the implementation found is ProductDao, and it is true; BUT, the type remains BaseDao
Means something like this BaseDao dao_i = new ProductDao();
and means whatever attributes defined inside ProductDao can not be called from dao_i, because BaseDao type higher than ProductDao.

what I really need is that ProductDao dao_i = new ProductDao();

So the importance of this question is how to return the dynamic type reference?

public <T> T getDao(String name)

Help me brainstorming, thanks.
Rob Spoor
Posts: 20820
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please UseCodeTags next time. I've added them for you this time.

You can't use generics based on just a String. However, the entire factory class is already generic, so if you create a DaoFactory<ProductDao> then getDao will already returned a ProductDao. You wouldn't even need the String parameter. It seems like your design is flawed though; I don't think you want the entire factory to be generic.

The closest I can think of is to a) remove the generics from the class itself, as it's not really used there (turning daos into a List<BaseDao> and using casting if using the cache), and b) move the generic type to be a method generic type and change the method signature to That does require your calling methods to get the Class object instead of create it from the name. Instead of getDao("product") you would need to call getDao(ProductDao.class).

After that you can use the generic type for your needs:
Now, you might also be able to still use the String parameter and use an unsafe cast (like the one you have now) but you will not be able to use type inference mostly. The compiler wouldn't know what DaoFactory.getDao("user") returned, so you would need to write DaoFactory.getDao<UserDao>("user").insert(), and you again defeat the purpose of using the String.

Another improvement: instead of using the List<BaseDao> which requires you to loop you may want to use a Map<Class<? extends BaseDao>,BaseDao>:
Don't worry about the "T dao = daoClazz.cast(daos.get(daoClazz));" line. It retrieves the value for daoClazz. Since you have full control over that map you know that that value is either null (if not cached yet) or an instance of the class key. You use the cast method to prevent any compiler warnings.

And by the way, you need to add a private constructor or anyone can use "new DaoFactory()" instead of having to use "DaoFactory.getInstance()".
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!