I have a question regarding use of Domain Model pattern for CRUD operations. In our project we are creating customer profiles. We have modeled profile like this
class Profile { Name name; List<Address> addressList; List <Phone> phoneList; .... }
We have CRUD operations for Profile, Addresses, and Phones. For crud operations, we have DAO facade as,
class ProfileClient { void testAddAddress() { Address address = new Address("112 Fifth Street", "NJ", "US", "08857");
String profileId = getProfileIdentifier();
getProfileDao().update(profileId, address);
} }
Instead of using DAO Facade , I thought we could use it like following.
1. Clients will do all CRUD operations on Profile object itself. 2. All the classes will have isUpdated, isNew and isDeleted flag. 3. Dao will have just one update(Profile p) method. 4. Dao will check for updates and make queries accordingly
void testAddAddress() { Address address = new Address("112 Fifth Street", "NJ", "US", "08857"); Profile p = getProfile(); p.addAddress(address);
getProfileDao().update(profile);
} }
This second approach looks cleaner, but the concern raised by my team mates is that every time I need to add, update, delete a single address, I need to load whole profile object in memory. This looks more like a "stateful" implementation as opposed to "stateless" implementation of Dao Facade. If Profile object is a huge one, then it can be a overkill to load the whole object just to add/change one address. But I certainly dont like the facade implementation. It does not allow me to do inserts/updates/deletes in batch. I have to do operations one at a time. Secondly any object level validations or business rules (Like Profile should have only one delivery address) are harder to implement in facade approach. What is your opinion on this? Is this a standard Domain Model vs Transaction Script issue?
It's a balance. In OO applications, you don't usually want your conceptual entities to be too granular (e.g. normalized) or too coarse (giant object graphs).
There are a number of additional considerations:
1) How long does it actually take to populate your complex object? Three queries may not be an issue.
2) Do you cache the object once populated? If so, it may be a very efficient approach (as those three queries will be executed rarely).
3) What unnatural payments will you be forced to make later if you don't populate it as a complex object?
4) Are there opportunities for lazy loading the remainder of the complex object, i.e. a single query for the main data and leave the rest unloaded until asked for.
5) What situations will CRUD break down completely for your application? (This, IMHO, is the one to watch out for the most!) For example, if you have to display a list of "n" Profile objects, is it three queries, or 3*n queries? etc.