Hi ,
Domain object model again ? .......sorry , because l am in chaos now.
Let's assume that l am designing a library automation system , and l want it to be a domain-driven design (no Anemic Domain Model in my code , http://www.martinfowler.com/bliki/An...mainModel.html) and l had choose Hibernate as my O/R mapper.
Let focus on three classes - LibraryUser , Borrow and Item in the system.
Tables Relationship:
LibraryUser --(1:M)--> Borrow <--(1:1)--> Item [<--(M:1)-- Book]
LibraryUser.java,
Borrow.java,Code:public class LibraryUser implements java.io.Serializable { private Long id; private Long version; private String cardKey; private String unifiedKey; private Date admissionDate; private Date expiryDate; private Set borrows = new HashSet(); private Set reservations = new HashSet(); private Set libraryUserTypes = new HashSet(); ..... // get , set }
Item.java,Code:public class Borrow implements java.io.Serializable { private Long id; private Long version; private Date borrowDate; private Date dueDate; private Date returnDate; private Date reportlostDate; private Short renewedNo; private LibraryUserType libraryUserType; private Item item; private LibraryUser libraryUser; ..... // get,set }
We have data (properties) in all three classes now , now l want to add some behaviours in the classes .Since this is a library system , borrow(loan) book action is a routine, so the first behaviour l want to add to the LibraryUser class is borrow method (any objection on this ? Is there any altenative way to place the borrow method if we want the design to be domain-driven?).Code:public class Item implements java.io.Serializable { private Long id; private Long version; private String barcode; private String shelfMark; private Date lastCheckin; private Set borrows = new HashSet(); private Book book; private ItemDuration itemDuration; private ItemStatus itemStatus; private ItemType itemType; private Location location; ..... // get,set }
If the above OK , then the method will be something like ,
Method 1.
LibraryUser.java,
then in my controller , l just feed the item , libraryUserType into the argument of the borrow method and save it,Code:public class LibraryUser implements java.io.Serializable { ..... public void borrow(Item item,LibraryUserType libraryUserType) { Borrow borrow = new Borrow(); borrow.setLibraryUser(this); borrow.setLibraryUserType(libraryUserType); borrow.setItem(item); borrow.setBorrowDate(new Date()); ... // The code here suppose to check the this libraryUser can borrow the item or not // l skip it for simple dicussion , let's assume that not checking is required. :) ... this.getBorrows().add(borrow); } }
controllerA,
this seem to be a natural way for me , because every libraryUser BORROW book, the borrow(method) behaviour should be own by libraryUser ... but if we store libraryUser(and if the libraryUser is detached) to cascade saving borrow this way , it will cause a lot of borrows to update ( http://forum.hibernate.org/viewtopic...beforeupdat e ), unless you set select-before-update="true" in class attribute of the borrow.hbm.xml, but this will cause a performance hit.Code:libraryUser.borrow(item,libraryUserType); getLibrary().storeLibraryUser(libraryUser);
Of course , we can do it another way , feed libraryUser, item , libraryUserType into borrow , and save borrow ,
Method 2.
ControllerB,
this method is the most natural way for relational database , saving a borrow , we need only LIBRARY_USER_ID, ITEM_ID and LIBRARY_USER_TYPE_ID , of course , with DUE_DATE , ...etc ,Code:Borrow borrow = new Borrow(); borrow.setLibraryUser(libraryUser); borrow.setLibraryUserType(libraryUserType); borrow.setItem(item); borrow.setBorrowDate(new Date()); ... getLibrary().storeBorrow(borrow);
it executes only one query ,
Q1. Is this an Anemic Domain Model way of coding (Method 2) ?Code:insert into BORROWS (VERSION, BORROW_DATE, DUE_DATE, RETURN_DATE, REPORTLOST_DATE, RENEWED_NO, LIBRARY_USER_TYPE_ID, ITEM_ID, USER_ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Q2. which is the domain-driven model way ? or l was wrong from the start ..![]()
moon


Reply With Quote
