Forums Register Login

Help me see if possible Generic DAO Factory

+Pie Number of slices to send: Send
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").insert();
DaoFactory.getDao("product").update();

where

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.
+Pie Number of slices to send: Send
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()".
And when my army is complete, I will rule the world! But, for now, I'm going to be happy with this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 4995 times.
Similar Threads
Did Jboss 5.1.0 supports EJB
Sychronization problem with hibernate and weblogic 9.2 JTA
Retrieving database values inside the <s:select> tag
Is this Dao?
Caching of Database Access Objects's possible?
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 29, 2024 03:48:16.