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