SpringSide是一個fantasy的好項目,可惜駑鈍,沒能加入其中,有時會看看它的代碼,吸取一些養分。
http://www.springside.org.cn/
今天先看看Springside的bookstore的domain設計,這不是springside的重點,先看看。
從hbm看起,在springside-bookstore/src/org.springside.bookstore.commons.domain.hbm下面放著這些hbm。
在Order.hbm.xml里面可以看到一個list映射。list映射可以按照順序持久化one-to-many關系。使用了<composite-element>映射后OrderItem就沒有單獨的class聲明了,完全以一種組件的形式被映射到Order里面。
有序的List映射是很方便的,這樣就可以通過List的set(int, Object)來改變OrderItem的順序,這個需求是經常被提起的。
Order.java里面可以看到在價格計算上使用了Rule,Rule是用String紀錄的rule id,我記得springside團隊試驗性的使用了Drools,具體在進步研究后分析。
Order實現了AclDomainAware接口,可見是用ACL進行了訪問控制。沒有繼承自統一的DomainObject基類,這個不知從何考慮,感覺Domain繼承自統一基類在框架很多地方都可以得到便利。實現接口在這里應該作為一種簽名標示,作為某些環節或者攔截器使用。SpringSide這里應該是用的是Acegi,可以看到這個是差沙同學實現的。
Order這部分就沒有什么其它特別之處了,是比較典型的pojo,貧血模型:D。在這里沒有看到全功能DomainModel的影子。此時修改Order里面的orderItems就需要手動替換,addProduct的功能都不在這里,的確有點不爽。
BTW:在Order.hbm.xml的配置里面可以看到上面有一行<import class="org.springside.bookstore.commons.domain.OrderItem"/>,不知道起什么作用,希望了解的朋友指點。
在Product.hbm.xml里面有一個繼承映射:“每個類分層結構一張表(Table per class hierarchy)”的形式。
再進到Product.java里面,它實現了HistorizableEntity接口,而前者又繼承自AuditableEntity。
從里面的注釋上看HistorizableEntity作為Hibernate Event Listener的記號,對此接口的領域對象自動保存修改紀錄,這個我找到代碼在org.springside.core.commons.support.audit.HistoryEventListener里面。這個東西被配置到session上。從代碼上看,這個東西用來記錄這個商品的LifeCycle,不過代碼還沒有完成,不知道calvin同學會用什么方法得到user等信息(Hibernate Listener是單例,不能有狀態信息)。這種方法在RoR里面有個_at和_on的后綴,可以自動完成修改時間等信息的持久化,不知道此處是否是要實現類似的功能。
Product里面有個@SearchableId、@SearchableProperty、@SearchableComponent的注釋,這是compass的注釋,這種暴露屬性提供搜索的配置方式非常舒服,是對pojo進行搜索的好例子。compass對Lucene的包裝是不錯的,這里好像是hellboys同學寫的,有時間深入看一下。
限制描述字段的功能放到了pojo里面,這個方法很不錯,大家也都在用。
Product的toString方法使用的是ToStringBuilder.reflectionToString,這個不知大家是否常用,不過這個東西大家要主要。比如在Domain公用基類中就不要用,否則它會對所有lazy load的屬性有毀滅性打擊:D。Springside沒有使用這種結構,當然沒關系。
Book是Product的子類,繼承是OO特性,這里顯然考慮周到,Springside也就不是僅能賣書的應用了:D。equals、hashCode方法都出現了重復。不過,重構強調任何形式的重復都是邪惡的,RoR的Hansson堅信之,所以有了CoC概念。
不過這里產生一個問題,我實現的一些應用中發現對于Hibernate的繼承,類型轉換是個令人頭疼的問題,相當不舒服,因為descrimitor對于你是不可見的,你很難在保留id的情況下強行轉換一個子類到另一個子類。這點很不靈活,不知大家有什么好辦法?
Custemer、Category是單純的Pojo。Category沒有實現層次,這點比較失望,感覺應該做一個樹形結構的顯示管理的demo。
下面的部分,我會繼續分析:D