Well, there's something bugging me in my project. I have lots and lots of hibernate entity classes and each one of them have their own DAO (inherited from a GenericDAO). Most of them have no specific funtion, being just an empty class inheriting GenericDAO.
Since I believe that those were unnecessary classes, I decided to get rid of them using reflection.
After some coding, my call on all of those classes that have no specific methods apart from GenericDAO follow this design:
DAO.forClass(MyClass.class, MyClassPK.class).genericDAOMethod();
It works like a charm. I'm now rid of empty DAOs. But after searching through internet, I have found low to no solution like mine, so the question is:
is this approach wrong or bad in any considerable way? Why no one ever consider doing something like this?
Reflection is almost never considered the answer to a problem. Its just hard to read because a lot of people don't know what it is and people that come behind you to modify your code cannot understand it easily. Its not "self-documenting" to use a term from the book Code Complete.
Reflection is powerful, as you just found out doing it to implement a DAO. But you should just be weary of it. A term we use around my office is "code stink", which is code that might be there for specific purpose, but shouldn't be used everywhere unless absolutely needed. Make sure to documented properly so that people that do actually come behind you will know what the heck it is.
I like to use it to write jUnit tests in Spring to compare two objects from two different databases using reflection. But that's a test and isn't actually in production code.
Hope this helps and is kind of what you are looking for!
Related
I am trying to get this answered, and found one comment in the MyBatis documentation:
Usually MapperFactoryBean is preferred to this class, since it
requires no extra code. But, this class(DAO) is useful if you need to do
other non-MyBatis work in your DAO and concrete classes are required and use SqlSessionDaoSupport or SqlSessionFactory
In case I chose to use MapperFactoryBean today in my project, but later I would need to use concrete DAO (may be because you may not do 100% using SQLs in mapper), then I need to change the design.
If the above is true, then MapperFactoryBean would be very less useful and would never(or mostly) be a choice.
In other words: Can MapperFactoryBean and DAO co-exists? Even if yes, should they be?
Are you aware of what this "non-MyBatis work" or "some dynamic SQL" how you call it exactly is? Well I'm not. But assuming writing Mappers is much faster and more intuitive for your developers you are saving a lot of time here. And when there are some scary non-MyBatis things to do why not writing then a very specific DAO which only does this one non-MyBatis thing?
+1 for coexistence ( DAO is not a must ! ) This is especially true if you are using mybatis in spring framework.
As for the refactoring part, it's good if you have incorpoproate a suitable testing framework to help out.
I have inherited a massive system from my predecessor and I am beginning to understand how it works but I cant fathom why.
It's in java and uses interfaces which, should add an extra layer, but they add 5 or 6.
Here's how it goes when the user interface button is pressed and that calls a function which looks like this
foo.create(stuff...)
{
bar.create;
}
bar.create is exactly the same except it calls foobar.creat and that in turn calls barfoo.create. this goes on through 9 classes before it finds a function that accessed the database.
as far as I know each extra function call incurs more performance cost so this seems stupid to me.
also in the foo.create all the variables are error checked, this makes sense but in every other call the error checks happen again, it looks like cut and paste code.
This seems like madness as once the variables are checked once they should not need to be re checked as this is just wastinh processor cycles in my opinion.
This is my first project using java and interfaces so im just confused as to whats going on.
can anyone explain why the system was designed like this, what benefits/drawbacks it has and what I can do to improve it if it is bad ?
Thank you.
I suggest you look at design patterns, and see if they are being used in the project. Search for words like factory and abstract factory initially. Only then will the intentions of the previous developer be understood correctly.
Also, in general, unless you are running on a resource constrained device, don't worry about the cost of an extra call or level of indirection. If it helps your design, makes it easier to understand or open to extension, then the extra calls are worth making.
However, if there is copy-paste in the code, then that is not a good sign, and the developer probably did not know what he was doing.
It is very hard to understand what exactly is done in your software. Maybe it even makes sense. But I've seen couple of projects done by some "design pattern maniacs". It looked like they wanted to demonstrate their knowledge of all sorts of delegates, indirections, etc. Maybe it is your case.
I cannot comment on the architecture without carefully examining it, but generally speaking separation of services across different layers is a good idea. That way if you change implementation of one service, other service remains unchanged. However this will be true only if there is loose coupling between different layers.
In addition, it is generally the norm that each service handles exceptions that specifically pertains to the kind of service it provides leaving the rest to others. This also allows us to reduce the coupling between service layers.
I know this question has been asked and answered many times, but I am still asking the same question again...
I have started working on a travelling application and for which currently I am working on creating on the creation of the underlying DAO so I am planning to create a generic DAO, its implementation and again an interface for each entity class.
My query is what is the best way to organise all these interfaces as well as their Implementation.
Thanks in advance
If I understand the question correctly your looking for suggestions on organising your packages?
I'd split then between. com.yyy.zzzz.dao.interfaces and com.yyy.zzzz.dao.impl
You're the only one who can take decisions on how your application should be organized. You can, of course, follow some recommandations such as the Java Naming Convention for packages, or even try to split your packages for each tier implied in your application; but in the end, you have to choose for yourself.
#Kevin D's solution is correct, you could use the com.company.project.dao.interfaces (I wouldn't use interfaces as it's a plural and I avoid plural in package names, but again it depends on you) and com.company.project.dao.impl or you could use packages to split different implementations. It's as you want. And no one should tell you how to split your own application (except your team).
The only (but still facultative) rule I would tell you to follow is "Have coherent names".
That means choose your project convention, but stick to it, and of course the names you choose for your packages (but it also applies on classes, variables) must represent their content (but I suppose this is common sense).
On another note, I don't know the context of your work, but you should really read Adam bien's Weblog, you'll see some articles on best practices regarding DAO and "default implementation", maybe it will concern your project.
Resources :
DAO's aren't dead - but they either collapsed or disappeared
Service s = new ServiceImpl() - Why are you doing that ? (not really related to DAO but still your "default implementation" made me think of this)
JPA/EJB3 killed the DAO
Not sure if the title captures what I'm trying to say here.
When designing in OO should I be splitting my objects up into their most specific areas - so if I have a factory object that deals with creating objects but later on i come across a way of creating objects for another purpose even though they may be the same objects is it worth creating a seperate fcatory or just add to the exsiting.
My biggest worry is bulking up classes with tons of stuff, or splitting objects and diluting my projects into a sea of classes.
Any help?
EDIT:
I guess on a side note/sub topic part of me wants to find out the level of granularity you should use in a program. Kind of, how low should you go?
My biggest worry is bulking up classes with tons of stuff, or
splitting objects and diluting my
projects into a sea of classes
This is a very valid point and in any even reasonably sized project, extremely difficult to get right up front especially because realistically, requirements themselves evolve over time in most cases.
This is where "Refactoring" come in. You design based on what you know at any given point and try not too make too many leaps of faith as to what you think the system MAY evolve to.
Given that you know what you are building right now, you design your classes trying to make the best possible use of OO concepts - eg encapsulation / polymorphism. This is itself, like others have noted as well, can be notoriously difficult to achieve and thats where experience, both in designing OO systems as well as knowledge of the domain can really come in handy.
Design based on what you know --> Build It --> Review it --> Refactor it --> Re-design --> and it goes on and on..
Finding the correct level of detail and responsibility is what makes OOP design so difficult. We can help you with a specific case but not with anything this general. If there were algorithms or strict methodologies of how to solve this, everyone could be an OOP designer.
A rule of thumb I like for deciding "is this getting too big now?" is "can I explain the purpose of it concisely?" If you start having to introduce caveats and lots of weasel words to explain the functions of a component of your design (be it class, member variable, method or whatever) it might be a good indicator that it's getting too complex and should be split up.
In your specific case, if you already have a factory object then the DRY Principle (Don't Repeat Yourself) would say that it's a bad idea to create another factory that does the same thing.
Is this an actual problem that you face? Or merely a fear about how your code might grow in the future?
If you are using the same type of object to solve drastically different problems then you may need to redesign the class to focus on seperation of concerns. If you need a more specific answer, you will need to provide an example of a type of class that would need this functionality.
I might have worded things badly in
the Q. I guess I wouldnt be repeating
myself its just more of a case of
where to put the code, it could be
added to an exsiting factory that
creates design objects for exporing
data to excel spreadsheets. On the
other hand I could see it could also
have its own factory for importing
excel data. Both factories would
produce the same objects but the inner
workings are completely different. –
If you aren't doing or plan on doing any class abstraction (subclassing or using interfaces) you may not need to use the factory pattern at all. The factory pattern is generally best suited for supplying objects of a base class type or that implement a specific interface.
Both
factories would produce the same
objects but the inner workings are
completely different.
Not sure if I've understood you correctly, but this sounds like a candidate for the AbstractFactory pattern.
I'm thinking of annotating my Domain Objects. This will ease manipulation of the DOs. Keeping the domain code free from other external stuff is also important for me.
Any comment on the "corruption" of the domain code by adding annotations?
Are you for/against adding annotation to Domain Objects, and why?
I think annotating if it makes the code simpler is a good idea, but, you should look at what is already out there, and at least use what may be a standard for your annotation names. For example you can look at JDBC 4.0, in Java (http://onjava.com/pub/a/onjava/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html?page=2), or Spring as examples.
This will do two things. One is that if you decide to move to using these annotations at some point, and get rid of your own, then your code won't change. Two, it shortens the learning curve for others.
Your annotations may not be going to the database, but there are numerous annotation models out there, just be certain if you create your own new names that you are doing something sufficiently unique otherwise it justs gets confusing for those that need to read your code.
Annotations (like most anything) have tradeoffs. The big one is that they are static. If you want to change during runtime a property represented in an annotation, you are out of luck.
They can get a little difficult to work with when you get into involved scenarios (especially when you deal with annotated annotations).
And if you have a lot of them, they can tend to make the code unreadable.
However, in moderation, kept simple and done right, they can really make code and configuration a lot simpler and cleaner.
Have a look at Terracotta - very possibly you don't have to write your own annotations. We were presented with similar dilemma (our DOs weren't intended for relation db) and Terracotta turned out to be a real life savior
We use annotations for specific things - i.e. special handling of Strings and the like - and it works like a charm. Annotations are a great way of handling "metadata" kind of information - data about the data object. I would recommend looking at the current J2EE annotations (I think it is version 5.0?) as that is used by most ORM systems (i.e. Hibernate and the like).
I prefer my annotations to be descriptive rather than functional. For example, the JCIP concurrency annotations describe information about a class, but don't provide functionality in an of themselves. Annotations that cause functionality tend to be PFM (pure effing magic) and make code more difficult to understand.
That's not a hard rule, but it's a pain when annotations do some of the functional configuration and configuration files (like XML) handle other configuration. It leads to code that requires you to look all over the place and understand multiple configuration schemes for how things are supposed to work.