需求: 某機(jī)構(gòu)體系下,機(jī)構(gòu)類(lèi)型分為子公司,部門(mén),人員等,以后可能在某機(jī)構(gòu)或者其子孫機(jī)構(gòu)下可能會(huì)再分出其他子機(jī)構(gòu)類(lèi)型,希望在增加新類(lèi)型過(guò)程中,盡可能的避免修改已有代碼。
情況:子公司,部分,人員等已完成所有編碼(界面,商業(yè)邏輯,數(shù)據(jù)邏輯)
變化:需要把這個(gè)機(jī)構(gòu)體系組成為一顆樹(shù)狀結(jié)構(gòu)
策略:鑒于除了樹(shù)結(jié)構(gòu)外的其他部分代碼已經(jīng)完成,那么應(yīng)該首先保持這些代碼不予改動(dòng)。復(fù)用修改的優(yōu)先級(jí)從高到低的順序如下:
? 界面×JSP,Action層
? 商業(yè)邏輯 Service層
? 數(shù)據(jù)邏輯層
? 數(shù)據(jù)物理層
有經(jīng)驗(yàn)的人知道,大部分情況下,越是下層的改動(dòng),越是影響越廣泛(注意不是修改難度),所以我們只有在無(wú)計(jì)可施的情況下,才進(jìn)行低層的修改。
分析: 回到我們的需求,從功能上看,維護(hù)一個(gè)組織機(jī)構(gòu)的需求,已經(jīng)涵蓋了每一個(gè)子結(jié)構(gòu)的維護(hù)需求,以部門(mén)的建立為例,在新建一個(gè)部門(mén)時(shí),同時(shí)也必須建立機(jī)構(gòu)樹(shù)上的節(jié)點(diǎn),
?這樣,如果需要直接使用原有的創(chuàng)建部門(mén)的所有代碼,需要在其上加上創(chuàng)建組織機(jī)構(gòu)所需要的父節(jié)點(diǎn),以及當(dāng)前節(jié)點(diǎn)名稱(chēng)信息(在這里department的增加界 面JSP是需要修改的,不過(guò)實(shí)際上我沒(méi)有修改該文件,而是利用DHTML來(lái)動(dòng)態(tài)加入需要新增加的信息),然后提交給原創(chuàng)建部門(mén)的URI (departmentSave.action)和組織機(jī)構(gòu)創(chuàng)建URI(orgCreate.action),在這里我們利用ww提供的action chain功能來(lái)完成這兩個(gè)操作。
?這里需要修改department.action的配置,攔截save方法使其執(zhí)行完后跳過(guò)原來(lái)的relist結(jié)果頁(yè)面轉(zhuǎn)向組織結(jié)構(gòu)的創(chuàng)建orgCreate.action:
?<action name="unitSave" class="com.wolfsquare.ibase.org.action.UnitAction" method="save">
?? <result name="input">/org/unit/input.jsp</result>
?? <result name="relist" type="chain">
?????? <param name="actionName">orgCreate</param>
??????????????? <param name="namespace">/org</param>??
??????????? </result>
?? <result name="xxx" type="redirect">/org/unit.action?start=${start}</result>
?? <interceptor-ref name="validationStack"/>
? </action>
可能有同學(xué)看到這里會(huì)問(wèn):創(chuàng)建組織節(jié)點(diǎn)時(shí)應(yīng)該還需要關(guān)聯(lián)前面創(chuàng)建的部門(mén)對(duì)象啊,這個(gè)操作是如何實(shí)現(xiàn)的?信息是如何傳遞的?
在這里,由于整個(gè)架構(gòu)體系并沒(méi)有支持這種信息傳遞的功能,所以只好以一種比較”臟“的方式實(shí)現(xiàn):
??????? 在department.action類(lèi)里增加了一個(gè)方法getModel()返回剛剛創(chuàng)建的部門(mén)對(duì)象,然后在org.action類(lèi)中增加一個(gè)接收的方法setModel(object o)這樣在整action chain執(zhí)行的時(shí)候,ww會(huì)自動(dòng)將getModel后的數(shù)據(jù)填入setModel中,這樣做的后果是以后增加新的機(jī)構(gòu)類(lèi)型的功能時(shí),action必須也照這樣的語(yǔ)意設(shè)置getModel方法。(如果要解決這個(gè)問(wèn)題,這能需要使用一個(gè)特定的Context,然后攔截指定Service的創(chuàng)建方法,把創(chuàng)建結(jié)果放入Context,不過(guò)這又帶來(lái)如何清除Context的問(wèn)題,于是又要求助與ww的interspector,專(zhuān)門(mén)寫(xiě)一個(gè)攔截器來(lái)擦屁股,夠麻煩。。。)
??????? 就這樣,我們完成了新增,修改組織機(jī)構(gòu)的功能合成,雖然有點(diǎn)拖沓,但是還是達(dá)到了復(fù)用,少修改原有代碼,而且擴(kuò)展性也很好的目標(biāo)。這上篇說(shuō)的是兩個(gè)簡(jiǎn)單業(yè)務(wù)的功能揉合問(wèn)題,下篇我們來(lái)看看稍微復(fù)雜點(diǎn)的情況,看看還能不能繼續(xù)依葫蘆畫(huà)瓢來(lái)完成功能合的成
??
(未完待續(xù))??