国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
敏捷思維: 架構(gòu)設(shè)計中的方法學(xué)(11)

敏捷思維: 架構(gòu)設(shè)計中的方法學(xué)(11)

精化和合并

級別: 初級

林星, 項目經(jīng)理, 辰訊軟件工作室

2002 年 11 月 01 日

對于一個已經(jīng)初步建立好的模型(分析模型或是設(shè)計模型)來說,對其進(jìn)行精化和合并是必要的步驟。

Context

建立架構(gòu)愿景,為架構(gòu)的設(shè)計定義了主要的設(shè)計策略和實現(xiàn)思路。應(yīng)用分層的原則則對整個的軟件進(jìn)行了結(jié)構(gòu)上的劃分,并定義了結(jié)構(gòu)的不同部分的職責(zé)。而現(xiàn)在,我們需要對初步完成的模型進(jìn)行必要的改進(jìn)。





Problem

我們?nèi)绾螌Τ跏技軜?gòu)模型進(jìn)行改進(jìn)?





Solution

對模型進(jìn)行改進(jìn)的活動可以分為精化和合并兩種。我們先從精化開始。

首先,我們手頭上的初始架構(gòu)模型已經(jīng)包括了總原則(參見架構(gòu)愿景模式)和層結(jié)構(gòu)(參見分層模式)兩部分的內(nèi)容?,F(xiàn)在我們要做的工作是根據(jù)需求和架構(gòu)原則來劃分不同的粗粒度組件。粗粒度組件來源于分析活動中的業(yè)務(wù)實體。把具有很強(qiáng)相關(guān)性業(yè)務(wù)實體組合起來,形成一個集合。集合內(nèi)部存在錯綜復(fù)雜的關(guān)系,同時集合向外部提供服務(wù)接口。這樣的集合就稱為粗粒度組件。粗粒度組件對外的接口和內(nèi)部的實現(xiàn)是相區(qū)分的。粗粒度組件的形式有很多,Java平臺上的Jar文件、Windows平臺上的dll文件,甚至古老的.o或.a文件都可以是粗粒度組件的表現(xiàn)形式。設(shè)計優(yōu)秀的粗粒度組件應(yīng)該只是完成一項功能,這一點是它與子系統(tǒng)的主要區(qū)分。一個系統(tǒng)中可能包括會計子系統(tǒng)、庫存管理子系統(tǒng)。但是提供會計粗粒度組件或是庫存管理粗粒度組件是沒有什么意義的。因為這樣的粗粒度組件的范圍過于廣泛,難以發(fā)揮重用的價值。

粗粒度組件是可以(可能也是必須)跨越層次的。粗粒度組件擁有持久化的行為,擁有業(yè)務(wù)邏輯,需要表示層的支持。這樣看起來,它所屬的軸向和層次的軸向是相互垂直的。

粗粒度組件來源于需求。需求階段產(chǎn)生的需求說明書或是用例模型將是粗粒度組件開發(fā)的基礎(chǔ)。在擁有了需求工件之后,我們需要對需求進(jìn)行功能性的劃分,將需求分為幾個功能組,這樣我們基本上就可以得到相應(yīng)的粗粒度組件了。如果系統(tǒng)比較龐大,可以對功能組再做細(xì)分。這取決于粗粒度組件的范圍。過小的范圍,將會造成粗粒度組件不容易使用,用戶需要理解不同的粗粒度組件之間的復(fù)雜關(guān)系,最后的結(jié)果也將包含大量的組件和復(fù)雜的邏輯。過大的范圍,則會造成粗粒度組件難以重用,導(dǎo)致粗粒度組件稱為一個子系統(tǒng)。

假設(shè)我們需要開發(fā)一個人力資源管理系統(tǒng)。經(jīng)過整理,它的需求大致分為這樣幾個部分:

  • 組織結(jié)構(gòu)的設(shè)計和管理:包括員工職務(wù)管理和員工所屬部門的管理。
  • 員工資料的管理:包括員工的基本資料和簡單的考評資料。
  • 日常事務(wù)的管理:包括了對員工的考勤管理和工資發(fā)放管理。

對于前兩項的功能組,我們認(rèn)為建立粗粒度組件是比較合適的。但是對于第三項功能組,我們認(rèn)為范圍過大,因為將之分為考勤管理和工資管理?,F(xiàn)在我們得到了四個粗粒度組件。分別是組織結(jié)構(gòu)組件、員工資料組件、員工考勤組件、員工工資組件。

在得到了粗粒度組件之后,我們的工作需要分為兩個部分:第一個部分是定義不同的粗粒度組件之間的關(guān)系。第二個部分是在粗粒度組件的基礎(chǔ)上定義業(yè)務(wù)實體或是定義細(xì)粒度組件。



不同的粗粒度組件之間的關(guān)系其實就是前文提到的粗粒度組件的外部接口。如果可能,在粗粒度組件之間定義單向的關(guān)聯(lián)(如上圖所示)可以有效的減少組件之間的耦合。如果必須要定義雙向的關(guān)聯(lián),請確保關(guān)聯(lián)雙方組件之間的一致性。在上圖中,我們可以清晰的看出,組織結(jié)構(gòu)處于最底層,員工資料依賴于組織結(jié)構(gòu),包括從組織結(jié)構(gòu)中獲得員工的所屬部門,以及員工職務(wù)等信息。而對于考勤、工資組件來說,需要從員工資料中獲取必要的信息,也包括了部門和職務(wù)兩方面的信息。這里有兩種關(guān)聯(lián)定義的方法,一種是讓考勤組件從組織結(jié)構(gòu)組件中獲得部門和職務(wù)信息,從員工資料中獲得另外的信息,另一種是如上圖一樣,考勤組件只從員工資料組件中獲得信息,而員工資料組件再使用委托,從組織結(jié)構(gòu)中獲得部門和職務(wù)的信息。第二種做法的好處是向考勤、工資組件屏蔽了組織結(jié)構(gòu)組件的存在,并保持了信息獲取的一致性。這里演示的只是組件之間的簡單關(guān)系,現(xiàn)實中的關(guān)系不可能如此的簡單,但是處理的基本思路是一樣的,就是盡可能簡化組件之間的關(guān)系,從而減少它們之間的耦合度。

考慮另一種的需求情況,在原先的系統(tǒng)的基礎(chǔ)上,我們又增加了會計子系統(tǒng)部分,其中的一個粗粒度組件是對部門、員工進(jìn)行成本分析。在原先的模型基礎(chǔ)上,我們增加了對分層的考慮。從下圖中,我們可以看到,組織結(jié)構(gòu)組件已經(jīng)發(fā)揮了它的重用性,被成本分析組件使用了。從分層上考慮(參見分層模式),我們將組織結(jié)構(gòu)組件劃分到工具層,而將其它的組件劃分到領(lǐng)域?qū)?,并在領(lǐng)域?qū)又羞M(jìn)行子系統(tǒng)級的劃分。從某個角度上來說,這種做法類似于一個分析模型的建模過程??傊?,這個過程中,最重要的就是定義好不同的組件的關(guān)系。盡管這中分析是初始的、模糊的。



在得到了粗粒度組件模型之后,我們需要對其進(jìn)行進(jìn)一步的分析,以得到細(xì)粒度的組件。細(xì)粒度的組件具有更好的重用性,并使得架構(gòu)設(shè)計的精化工作更進(jìn)一步。按Jacobson推薦的面向?qū)ο筌浖こ蹋∣OSE)的做法,我們需要從軟件的目標(biāo)領(lǐng)域中識別出關(guān)鍵性的實體,或者說是領(lǐng)域中的名詞。例如上例中的員工、部門、工資等。然后決定它們應(yīng)該歸屬于哪些粗粒度組件。先識別細(xì)粒度組件還是先識別粗粒度組件并沒有固定的順序。

最初得到的組件模型可能并不完善,需要對其進(jìn)行修改??赡苣硞€組件中的類太多了,過于復(fù)雜,我們就需要對其進(jìn)一步精化、分為更細(xì)的組件,也許某個組件中的類太少了,需要和其它的組件進(jìn)行合并。也許你會發(fā)現(xiàn)某兩個組件之間存在重復(fù)的要素,可以從中抽取出共性的部分,形成新的組件。組件分析的過程并沒有一種標(biāo)準(zhǔn)的做法,你只能夠根據(jù)具體的案例來進(jìn)行分析。到最后,你可能會為其中的幾個類的歸屬而苦惱不已,不要在它們身上浪費太多的時間,盡善盡美的模型并不存在。

最后的模型將會明確的包含幾個經(jīng)過精化之后的粗粒度組件。粗粒度組件之間的關(guān)系也會進(jìn)行一次重新定義。如果這時候,粗粒度組件之間仍然存在著復(fù)雜的關(guān)系,也許意味著你的業(yè)務(wù)邏輯比較復(fù)雜,因此這個部分需要你投入比較多的精力來處理。當(dāng)然,你可以通過一些技巧來減少不同組件之間的耦合程度。這里有幾種可參考的辦法:

第一種方法是使用外觀(Facade)模式(在分層模式中,我們就提到過外觀模式)。如下圖所示,新引入的BusinessFacade類充當(dāng)了外觀的角色,將調(diào)用者和復(fù)雜的業(yè)務(wù)類隔離了起來,調(diào)用者無須知道業(yè)務(wù)類之間的復(fù)雜的關(guān)系,就能夠進(jìn)行業(yè)務(wù)處理,從而大大降低了調(diào)用者和業(yè)務(wù)類之間的耦合度。這種方法在實踐中經(jīng)常被采用,適合用在內(nèi)部關(guān)系較為復(fù)雜的組件中,也適合用在業(yè)務(wù)層向表示層發(fā)布接口的情況中。對于外觀模式來說,我們可以在BusinessFacade類的業(yè)務(wù)方法中提供參數(shù),來實現(xiàn)數(shù)據(jù)的傳遞。這對于一些數(shù)據(jù)較少的情景特別的適用。如果當(dāng)數(shù)據(jù)種類較多時,也可以使用參數(shù)類或值類來達(dá)到數(shù)據(jù)傳送的目的。



第二種方法是使用命令(Command)模式,該模式也來自于設(shè)計模式一書。在處理參數(shù)時,命令模式使用了一系列的set方法來逐一設(shè)置參數(shù),最后調(diào)用execute()來執(zhí)行業(yè)務(wù)邏輯。命令模式的好處是為調(diào)用者提供了統(tǒng)一的接口,調(diào)用者并不需要關(guān)心具體的業(yè)務(wù)邏輯,他需要做的就是設(shè)置數(shù)據(jù),并調(diào)用execute()方法。如果遇到業(yè)務(wù)邏輯需要用到較多的參數(shù),逐個的調(diào)用set方法過于麻煩了,也可以提供一個setValues()方法來處理多個參數(shù)。當(dāng)然,該模式也有其弱點,如果業(yè)務(wù)方法太多,那么相應(yīng)的Command類也會隨之增多。這是我們不希望看到的。





除了上面介紹的兩種方法以外,還可以使用諸如工廠(Factory)模式、業(yè)務(wù)代表(Business Delegate)模式等方法來減少不同組件之間的耦合度。應(yīng)該認(rèn)識到,不同的設(shè)計模式有其不同的上下文環(huán)境,在架構(gòu)設(shè)計中使用設(shè)計模式(以及分析模式)有助于優(yōu)化設(shè)計,但是請注意模式的上下文環(huán)境,誤用或濫用模式反而會導(dǎo)致設(shè)計的失誤。

以上介紹的方法除了能夠降低不同的組件之間的耦合度之外,還可以起到向調(diào)用者隱藏實現(xiàn)的功能。這一點對于重構(gòu)活動(參見Refactoring模式)非常的關(guān)鍵,因為它可以有效的緩解在對組件進(jìn)行重構(gòu)時將變化擴(kuò)散到其它的組件中。

精化是對模型進(jìn)行改進(jìn)的第一步。完成的模型基本上代表了最終的軟件。但如果我們對其進(jìn)行認(rèn)真的檢查,我們會發(fā)現(xiàn)模型仍然存在問題。這時候的問題主要體現(xiàn)在設(shè)計模型過于肥大了。如果說精化使得模型變得復(fù)雜,那么合并就是使得模型變得簡單。千萬不要以為這兩項工作是互斥的,通過這兩項活動,可以使得模型得到極大的改進(jìn)。

還記得我們在簡單設(shè)計模式中提到的簡單原則嗎?在進(jìn)入下面的討論之前,請確保你能夠理解簡單原則,這是敏捷的核心原則之一。

在上文中我們提到了一些設(shè)計模式的使用,而在整個的敏捷架構(gòu)設(shè)計的文章中,我們也大量地討論了模式。而在很多時候,我們其實是在不恰當(dāng)?shù)氖褂媚J絹斫鉀Q一些簡單的問題。所以,在使用模式之前,我們應(yīng)該回顧需求說明書(或是用例模型)上的相關(guān)部分,確定是否需要使用模式。

在一次的設(shè)計軟件的持久性機(jī)制的時候,我選用了DTO(Data Transfer Object)模式作為持久層的實現(xiàn)機(jī)制。原因只是我在前一天晚上看了這個模式,并覺得它很酷??雌饋砦沂欠噶四J骄C合癥了(當(dāng)學(xué)習(xí)了一個模式之后,就想方設(shè)法的使用它)。在花費了很多的時間學(xué)習(xí)并實現(xiàn)該模式之后,我發(fā)現(xiàn)該模式并沒能夠發(fā)揮它應(yīng)有的作用。原因是,模式的上下文環(huán)境并不適合用在目前的軟件中,原本只需要用JDBC就可以實現(xiàn)的功能,在使用了模式之后,反而變得復(fù)雜了。糟糕的是,我不得不向開發(fā)人員解釋這個模式,吹捧這個設(shè)計模式的精妙之處。但是結(jié)果令人不安。開發(fā)人員顯然不能夠理解這個模式在這里發(fā)揮了什么樣的作用。最后,我去掉了這個模式,設(shè)計得到了簡化。

同樣的,在開發(fā)過程還存在各種各樣的過度設(shè)計的例子,尤其是數(shù)據(jù)庫訪問、線程安全、一致性等方面的設(shè)計。這些問題往往需要花費大量的時間來處理,但是他們的價值卻并不高,尤其是小型的系統(tǒng)。當(dāng)然,在設(shè)計一些大型的系統(tǒng)時,這些問題是必須要考慮的。

而當(dāng)使用設(shè)計模式在對不同的組件進(jìn)行整合的時候,我們也需要對組件的行為進(jìn)行合并。將不同組件之間的相同的行為合并到一個組件中,尤其是那些關(guān)系非常復(fù)雜的組件。這樣可以把復(fù)雜的關(guān)系隱藏到組件內(nèi)部,而簡化其對外提供的接口。

很難評判設(shè)計是否已經(jīng)完成了。這里有兩個不同的極端?;ㄙM了過多的時間在初始設(shè)計上,以及過度的迭代。在初始模型上花費太多的時間并不一定能夠得到盡善盡美的模型,相反的,可能還會因為設(shè)計師鉆牛角尖的行為導(dǎo)致設(shè)計模型的失誤。而在過于頻繁的迭代對于改進(jìn)模型同樣沒有好處,因為實際上,你不是在改進(jìn)模型,而是在改變模型。請區(qū)分這兩種完全不同的行為,雖然它們似乎很相似。在Refactoring模式中,我們還會進(jìn)一步對迭代和模型改進(jìn)進(jìn)行討論。

一種判斷方法是請編碼人員來評判設(shè)計是否完成。設(shè)計模型最后是要交給編碼人員,指導(dǎo)編碼人員的開發(fā)工作的。因此,如果編碼人員無法理解模型,這個模型設(shè)計的再好看,也沒有太大的作用。另一方面,如果編碼人員認(rèn)為模型已經(jīng)足夠指導(dǎo)開發(fā)工作了,那么還有什么必要再畫蛇添足下去了呢?不同水平、不同經(jīng)驗的編碼人員對模型的要求也不一樣。在我們的工作中,對資深開發(fā)人員和開發(fā)新手的發(fā)布的模型是不一樣的。對于資深的開發(fā)人員而言,可能只需要對他說,在組件A和組件B之間使用外觀模式,他就能夠理解這句話的意思,并立即著手開發(fā),可是對于沒有經(jīng)驗的開發(fā)人員,就需要從模式理論開始進(jìn)行講述。對于他們來說,設(shè)計模型必須足夠充分,足夠細(xì)致。設(shè)置需要把類、方法、參數(shù)、功能描述全部設(shè)計出來才可以。

復(fù)審是避免設(shè)計模型出現(xiàn)錯誤的重要手段。強(qiáng)烈建議在架構(gòu)設(shè)計過程中引入復(fù)審的活動。復(fù)審對于避免設(shè)計錯誤有著重大的幫助。復(fù)審應(yīng)該著重于粗粒度組件的分類和粗粒度組件之間的關(guān)系。正如后續(xù)的Refactoring模式和穩(wěn)定性模式所描繪的那樣,保持粗粒度組件的穩(wěn)定性有助于重構(gòu)行為,有助于架構(gòu)模型的改進(jìn)。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
SOA定義
如何在短頻快的節(jié)奏中做好技術(shù)?業(yè)務(wù)開發(fā)必會的架構(gòu)思維
軟件架構(gòu)發(fā)展歷程分享
軟件架構(gòu)設(shè)計系列總結(jié)
架構(gòu)設(shè)計:業(yè)務(wù)邏輯層簡述
企業(yè)運營模式模型一覽(咨詢派)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服