通過上一章的介紹,我們對敏捷和方法有了一個大致的了解,從這一章起,我們開始對軟件開發過程中架構設計的研究。記住一點,我們并不是為了架構設計而研究架構設計,我們的目的在于敏捷方法學的應用。
架構設計是一種權衡(trade-off)。一個問題總是有多種的解決方案。而我們要確定唯一的架構設計的解決方案,就意味著我們要在不同的矛盾體之間做出一個權衡。我們在設計的過程總是可以看到很多的矛盾體:開放和整合,一致性和特殊化,穩定性和延展性等等。任何一對矛盾體都源于我們對軟件的不同期望??墒?,要滿足我們希望軟件穩定運行的要求,就必然會影響我們對軟件易于擴展的期望。我們希望軟件簡單明了,卻增加了我們設計的復雜度。沒有一個軟件能夠滿足所有的要求,因為這些要求之間帶有天生的互斥性。而我們評價架構設計的好壞的依據,就只能是根據不同要求的輕重緩急,在其間做出權衡的合理性。
目標
我們希望一個好的架構能夠:
重用:為了避免重復勞動,為了降低成本,我們希望能夠重用之前的代碼、之前的設計。重用是我們不斷追求的目標之一,但事實上,做到這一點可沒有那么容易。在現實中,人們已經在架構重用上做了很多的工作,工作的成果稱為框架(Framework),比如說Windows的窗口機制、J2EE平臺等。但是在企業商業建模方面,有效的框架還非常的少。
透明:有些時候,我們為了提高效率,把實現的細節隱藏起來,僅把客戶需求的接口呈現給客戶。這樣,具體的實現對客戶來說就是透明的。一個具體的例子是我們使用JSP的tag技術來代替JSP的嵌入代碼,因為我們的HTML界面人員更熟悉tag的方式。
延展:我們對延展的渴求源于需求的易變。因此我們需要架構具有一定的延展性,以適應未來可能的變化??墒?,如上所說,延展性和穩定性,延展性和簡單性都是矛盾的。因此我們需要權衡我們的投入/產出比。以設計出具有適當和延展性的架構。
簡明:一個復雜的架構不論是測試還是維護都是困難的。我們希望架構能夠在滿足目的的情況下盡可能的簡單明了。但是簡單明了的含義究竟是什么好像并沒有一個明確的定義。使用模式能夠使設計變得簡單,但這是建立在我熟悉設計模式的基礎上。對于一個并不懂設計模式的人,他會認為這個架構很復雜。對于這種情況,我只能對他說,去看看設計模式。
高效:不論是什么系統,我們都希望架構是高效的。這一點對于一些特定的系統來說尤其重要。例如實時系統、高訪問量的網站。這些值的是技術上的高效,有時候我們指的高效是效益上的高效。例如,一個只有幾十到一百訪問量的信息系統,是不是有必要使用EJB技術,這就需要我們綜合的評估效益了。
安全:安全并不是我們文章討論的重點,卻是架構的一個很重要的方面。
規則
為了達到上述的目的,我們通常需要對架構設計制定一些簡單的規則:
功能分解
顧名思義,就是把功能分解開來。為什么呢?我們之所以很難達到重用目標就是因為我們編寫的程序經常處于一種好像是重復的功能,但又有輕微差別的狀態中。我們很多時候就會經不住誘惑,用拷貝粘貼再做少量修改的方式完成一個功能。這種行為在XP中是堅決不被允許的。XP提倡"Once and only once",目的就是為了杜絕這種拷貝修改的現象。為了做到這一點,我們通常要把功能分解到細粒度。很多的設計思想都提倡小類,為的就是這個目的。
所以,我們的程序中的類和方法的數目就會大大增長,而每個類和方法的平均代碼卻會大大的下降??墒?,我們怎么知道這個度應該要如何把握呢,關于這個疑問,并沒有明確的答案,要看個人的功力和具體的要求,但是一般來說,我們可以用一個簡單的動詞短語來命名類或方法的,那就會是比較好的分類方法。
我們使用功能分解的規則,有助于提高重用性,因為我們每個類和方法的精度都提高了。這是符合大自然的原則的,我們研究自然的主要的一個方向就是將物質分解。我們的思路同樣可以應用在軟件開發上。除了重用性,功能分解還能實現透明的目標,因為我們使用了功能分解的規則之后,每個類都有自己的單獨功能,這樣,我們對一個類的研究就可以集中在這個類本身,而不用牽涉到過多的類。