This week's book giveaway is in the OCAJP forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide 1Z0-808 and have Jeanne Boyarsky & Scott Selikoff on-line! See this thread for details.
I have some questions concerning the DAO pattern that the examples I've run across seem not to address. Let's say I've got the following objects: Moose --------- String name int numberOfEyes (getters, setters, some other methods) Ranch --------- String name Collection mooseHerd (a Collection of Moose objects) addMoose(Moose) (getters, setters, some other methods) My question is concerning the Value Objects and Data Access Objects. I would assume that a RanchVO would have a Collection of MooseVOs, but is that assumption correct? If so then retrieving a Ranch from the DAO would pass a VO along with its collection of MooseVOs, right? In addition to the RanchDAO, would there be a MooseDAO? If this is the case, since transaction control is handled in the DAO, would the RanchDAO interact with the MooseDAO. The business object interacting with the two DAOs, particularly when saving the state of the Ranch would include saving the state of all associated Mooses, would seem to put transaction control in the business object rather than the DAO. Is there anybody able to slap me around a bit and straighten me out? Does anyone know of any examples similar to this, where a business object has a relation to another business object?
Let's use a different example. I recently designed an Employee Performance Review system for my company, so I'll use the relationship between a review and its remarks. Review ------ reviewId (int) reviewYear (int) reviewRemarks (Collection) Remark ------ remarkId (int) remarkText (String) Basically, a review can have several remarks, so the relationship is 0-to-many. The relationship is a composition, in that a remark cannot exist if the review is destroyed. From the DAO perspective, there will probably exist a ReviewDAO, which is responsible for creating a Review object by retrieving info from a datasouce and bulding the Review, which also includes its remarks. Since the remarks are closely coupled to the review, there is probably no need to create an individual DAO for the Remark object. Basically, you have 1 DAO for a top-level entity that is an aggregation or composition of other entities. Keep in mind that there are exceptions to every rule. Your system may employ only a few top-level entities to which all other entities are associated, in which case you may need to divide the responsibility across several DAO's for creating the top-level and aggregate objects. Also, if your top-level entity is an aggregate of several other entities via 1-to-1 mapping, you may want to stick to a single DAO since, from an SQL perspective, you can select and join 1-to-1 mappings in a single statement, but if you start using separate DAOs even for 1-to-1-mapped entities, you're making unnecessary database calls because the DAOs now need to call other DAOs. Raffi [ June 11, 2003: Message edited by: SAFROLE YUTANI ]
I would assume that a RanchVO would have a Collection of MooseVOs, but is that assumption correct? I think so. If so then retrieving a Ranch from the DAO would pass a VO along with its collection of MooseVOs, right? That depends entirely on business requirements. I recently worked on a Mammography DB app where a patient has 1 or more lesions and each lesion has 1 or more biopsies done on it. Througout the app I never had to load all records for a patient. In all the cases, a user would only be working either on a patient object, a specific lesion for a patient object or a specific biopsy. So there really was never a need to load all lesions and their biopsies. However, I did put a method in patient DAO which optionally loads all the lesions and their biopsies. In addition to the RanchDAO, would there be a MooseDAO? Absolutely. Suppose you want to remove the Moose from the ranch and put it in a truck (on it's way to slaughterhouse or to be released back into wild), how would you save the Moose's state since it's not in the Ranch anymore? If this is the case, since transaction control is handled in the DAO, would the RanchDAO interact with the MooseDAO. The business object interacting with the two DAOs, particularly when saving the state of the Ranch would include saving the state of all associated Mooses, would seem to put transaction control in the business object rather than the DAO. From what I learned - DAO is only supposed to know how to save/update/retrieve/delete a particular object. So transaction control would automatically be the responsibility of business object since you might want to update multiple objects in one transcation. I hope this helps you get back on the tracks.
WRT VO In Martin Fowler's book "Patterns of Enterprise Application Architecture" he lays out two patterns: "Data Transfer Object (DTO)" and "Value Object (VO)". He explains his DTO as what everybody thinks is a DTO and what we call VO (as well as some of the J2EE guys - well, at least they used to ...). He explains that VO is like the Integer class or Double class. Particularly of note is this paragraph in his description of VO: Name Collisions I've seen the term Value Object used for this pattern for quite some time. Sadly recently I've seen the J2EE community [Alur et al.] use the term "value object" to mean Data Transfer Object, which has caused a storm in the teacup of the patterns community. This is just one of those clashes over names that happen all the time in this business. Recently [Alur et al.] decided to use the term transfer object instead. Just thought this was interesting....
I think your DAO objects would have methods that reflect your business needs. One DAO class would probably work with a half dozen tables, maybe more.
Joined: Nov 09, 2000
Thanks for all the really excellent responses! I still have a couple of questions though. For one, am I correct or mistaken in assuming that a DAO method should encapsulate a complete transaction? It would seem the alternative would be a business object possibly having to make calls to multiple DAOs in order to complete a transaction. I'm thinking of a case like a with the Ranch BO having Moose BOs, and there existing a RanchDAO and a MooseDAO. This might mean that there would also have to be some kind of commit/rollback mechanisms implemented in the BO as well (since jdbc calls are all handled in the DAOs). It would also seem that calls to multiple DAOs would be inefficient since multiple connections would have to be made to complete a single transaction. So if my assumption is correct in that a DAO method should encapsulate a complete transaction, and again using the Ranch/Moose example... For one, let's make the assumption that a Moose does not need to be tightly coupled with a Ranch, so there would still be a requirement for a MooseDAO. I have read about using delegate objects, called by the DAOs, to actually encapsulate the majority of the JDBC code in order to keep the DAOs cleaner, and I was thinking about doing the same. This is what I've come up with as one possible case:
I was thinking that I would still have a MooseDAO which would be used in cases where the Moose was decoupled from the ranch and had to perform some kind of persistance operation on itself. Am I heading down the right track here?
Joined: Oct 12, 2000
I think these links will help... Composite Entity Pattern and DAO Pattern Here's the brief proccess: If an object can not exist without another one - then use Composite Entity. In other words, Your topmost DAO object will use other DAOs for dependent objects. In this case I'm guessing that the topmost DAO will open the connection and pass it along to the dependent objects for transaction control. But then again if an object can be used as a dependent object and as a topmost (self suffcient) object, then what do you do? Safest thing to do would be to remove connection stuff from the DAO and put it in business object for transaction control.
Originally posted by Bhupinder Dhillon: But then again if an object can be used as a dependent object and as a topmost (self suffcient) object, then what do you do?
Design the DAO in a way that it can both accept transactions from other DAOs and create its own when called directly from a business object?
Safest thing to do would be to remove connection stuff from the DAO and put it in business object for transaction control.
In my not so humble opinion, that would be a bad idea. The whole purpose of the DAO is to encapsulate the persistence mechanism and make the business objects unaware of it (conforming to the Single Responsibility Principle). You do this to be able to switch to a different persistence mechanism without needing to touch the business objects. Letting the business object being aware of transaction mechanism breaks that encapsulation and more or less makes a nonsense of using the DAO pattern at all...
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
FWIW .... in the last few years I've encountered a lot of difference of opinion on what DAO means to different engineers. Some think it means a one-to-one with a table or a view. Some thinks it is a bit higher level: an object model interface that talk to one or more tables/views on the database.
Originally posted by Paul Wheaton: FWIW .... in the last few years I've encountered a lot of difference of opinion on what DAO means to different engineers. Some think it means a one-to-one with a table or a view. Some thinks it is a bit higher level: an object model interface that talk to one or more tables/views on the database.
I think you need to go back to the Core J2EE Design Patterns for the definition:
Although a one-to-one relationship is easy to understand, there's no reason in the design pattern why there should not be one-to-many relationships (actually, it's one of the most commonly used features in FireStorm/DAO).
PJ Murray -
Joined: Jul 11, 2001
Also keep in mind that a DAO doesn't have to return DTOs (VOs). Often they simply can create and return the true businnes objects.