<a href="https://www.ibm.com/developerworks/cn/rational/06/r-wenyu/index.html" target="_blank">https://www.ibm.com/developerworks/cn/rational/06/r-wenyu/index.html</a>
<a href="https://www.ibm.com/developerworks/cn/rational/r-4p1-view/" target="_blank">https://www.ibm.com/developerworks/cn/rational/r-4p1-view/</a>
靈感一閃,就想出了把大象放進冰箱的辦法,這自然好。但希望每個架構設計政策都依靠靈感是不現實的--我們需要系統方法的指導。
需要架構設計的多重視圖方法,從根本上來說是因為需求種類的複雜性所緻。以工程領域的例子開道吧。比如設計一座跨江大橋:我們會考慮"連接配接南北的公路交通"這個"功能需求",進而初步設計出理想化的橋墩支撐的公路橋方案;然後還要考慮造橋要面臨的"限制條件",這個限制條件可能是"不能影響萬噸輪從橋下通過",于是細化設計方案,規定橋墩的高度和橋墩之間的間距;另外還要顧及"大橋的使用期品質屬性",比如為了"能在湍急的江流中保持穩固",可以把大橋橋墩深深地建在岩石層之上,和大地渾然一體;其實,"建造期間的品質屬性"也很值得考慮,比如在大橋的設計過程中考慮"施工友善性"的一些措施。
和工程領域的功能需求、限制條件、使用期品質屬性、建造期間的品質屬性等類似,軟體系統的需求種類也相當複雜,具體分類如圖1所示。

例子是最好的老師。為了更好地了解軟體需求種類的複雜性,我們來分析一個實際的例子。在表1中,我們列舉了一個典型的超市系統的需求子集,從這個例子中可以清晰地看到需求可以分為兩大類:功能需求和非功能需求。
簡單而言,功能需求就是"軟體有什麼用,軟體需要做什麼"。同時,注意把握功能需求的層次性是軟體需求的最佳實踐。以該超市系統為例:
超市老闆希望通過軟體來"提高收銀效率"。
那麼,你可能需要為收銀員提供一系列功能來促成這個目的,比如供收銀員使用的"任意商品項可單獨取消"功能有利于提供收銀效率(筆者曾在超市有過被迫整單取消然後一車商品重新掃描收費的痛苦經曆)。
而具體到這個超市系統,系統分析員可能會決定要提供的具體功能為:通過收銀終端的按鍵組合,可以使收銀過程從"逐項錄入狀态"進入"選擇取消狀态",進而取消某項商品。
從上面的例子中我們還驚訝地發現,非功能需求--人們最經常忽視的一大類需求--包括的内容非常寬、并且極其重要。非功能需求又可以分為如下三類:
限制。要開發出使用者滿意的軟體并不是件容易的事,而全面了解要設計的軟體系統所面臨的限制可以使你向成功邁進一步。限制性需求既包括企業級的商業考慮(例如"項目預算有限"),也包括最終使用者級的實際情況(例如"使用者的平均電腦操作水準偏低");既可能包括具體技術的明确要求(例如"要求能在Linux上運作"),又可能需要考慮開發團隊的真實狀況(例如"開發人員分散在不同地點")。這些限制性需求當然對架構設計影響很大,比如受到"項目預算有限"的限制,架構師就不應選擇昂貴的技術或中間件等,而考慮到開發人員分散在不同地點",就更應注重軟體子產品職責劃分的合理性、松耦合性等等。
運作期品質屬性。這類需求主要指軟體系統在運作期間表現出的品質水準。運作期品質屬性非常關鍵,因為它們直接影響着客戶對軟體系統的滿意度,大多數客戶也不會接受運作期品質屬性拙劣的軟體系統。常見的運作期品質屬性包括軟體系統的易用性、性能、可伸縮性、持續可用性、魯棒性、安全性等。在我們的超市系統的案例中,使用者對高性能提出了具體要求(真正的性能需求應該量化,我們的表1沒展現),他們不能容忍金額合計超過2秒的延時。
開發期品質屬性。這類非功能需求中的某些項人們倒是念念不忘,可惜很多人并沒有意識到"開發期品質屬性"和"運作期品質屬性"對架構設計的影響到底有何不同。開發期品質屬性是開發人員最為關心的,要達到怎樣的目标應根據項目的具體情況而定,而過度設計(overengineering)會花費額外的代價。
那麼,什麼是軟體架構視圖呢?Philippe Kruchten在其著作《Rational統一過程引論》中寫道:
一個架構視圖是對于從某一視角或某一點上看到的系統所做的簡化描述,描述中涵蓋了系統的某一特定方面,而省略了于此方面無關的實體。
也就是說,架構要涵蓋的内容和決策太多了,超過了人腦"一蹴而就"的能力範圍,是以采用"分而治之"的辦法從不同視角分别設計;同時,也為軟體架構的了解、交流和歸檔提供了友善。
值得特别說明的,大多數書籍中都強調多視圖方法是軟體架構歸檔的方法,其實不然。多視圖方法不僅僅是架構歸檔技術,更是指導我們進行架構設計的思維方法。
1995年,Philippe Kruchten在《IEEE Software》上發表了題為《The 4+1 View Model of Architecture》的論文,引起了業界的極大關注,并最終被RUP采納。如圖2所示。
該方法的不同架構視圖承載不同的架構設計決策,支援不同的目标和用途:
邏輯視圖:當采用面向對象的設計方法時,邏輯視圖即對象模型。
開發視圖:描述軟體在開發環境下的靜态組織。
處理視圖:描述系統的并發和同步方面的設計。
實體視圖:描述軟體如何映射到硬體,反映系統在分布方面的設計。
如前文所述,要開發出使用者滿意的軟體并不是件容易的事,軟體架構師必須全面把握各種各樣的需求、權衡需求之間有可能的沖突之處,分門别類地将不同需求一一滿足。
Philippe Kruchten提出的4+1視圖方法為軟體架構師"一一征服需求"提供了良好基礎,如圖3所示。
邏輯視圖。邏輯視圖關注功能,不僅包括使用者可見的功能,還包括為實作使用者功能而必須提供的"輔助功能子產品";它們可能是邏輯層、功能子產品等。
開發視圖。開發視圖關注程式包,不僅包括要編寫的源程式,還包括可以直接使用的第三方SDK和現成架構、類庫,以及開發的系統将運作于其上的系統軟體或中間件。開發視圖和邏輯視圖之間可能存在一定的映射關系:比如邏輯層一般會映射到多個程式包等。
處理視圖。處理視圖關注程序、線程、對象等運作時概念,以及相關的并發、同步、通信等問題。處理視圖和開發視圖的關系:開發視圖一般偏重程式包在編譯時期的靜态依賴關系,而這些程式運作起來之後會表現為對象、線程、程序,處理視圖比較關注的正是這些運作時單元的互動問題。
實體視圖。實體視圖關注"目标程式及其依賴的運作庫和系統軟體"最終如何安裝或部署到實體機器,以及如何部署機器和網絡來配合軟體系統的可靠性、可伸縮性等要求。實體視圖和處理視圖的關系:處理視圖特别關注目标程式的動态執行情況,而實體視圖重視目标程式的靜态位置問題;實體視圖是綜合考慮軟體系統和整個IT系統互相影響的架構視圖。
本文的以下部分,将研究一個案例:某型号裝置調試系統。
裝置調試員通過使用該系統,可以察看裝置狀态(裝置的狀态資訊由專用的資料采集器實時采集)、發送調試指令。該系統的用例圖如圖4所示。
經過研制方和委托方的緊密配合,最終确定的需求可以總括地用表2來表示。
下面運用RUP推薦的4+1視圖方法,從不同視圖進行架構設計,來分門别類地将不同需求一一滿足。
首先根據功能需求進行初步設計,進行大粒度的職責劃分。如圖5所示。
應用層負責裝置狀态的顯示,并提供模拟控制台供使用者發送調試指令。
應用層使用通訊層和嵌入層進行互動,但應用層不知道通訊的細節。
通訊層負責在RS232協定之上實作一套專用的"應用協定"。
當應用層發送來包含調試指令的協定包,由通訊層負責按RS232協定将之傳遞給嵌入層。
當嵌入層發送來原始資料,由通訊層将之解釋成應用協定包發送給應用層。
嵌入層負責對調試裝置的具體控制,以及高頻度地從資料采集器讀取裝置狀态資料。
裝置控制指令的實體規格被封裝在嵌入層内部,讀取數采器的具體細節也被封裝在嵌入層内部。
<a href="https://www.ibm.com/developerworks/cn/rational/06/r-wenyu/index.html#ibm-pcon"> </a>
軟體架構的開發視圖應當為開發人員提供切實的指導。任何影響全局的設計決策都應由架構設計來完成,這些決策如果"漏"到了後邊,最終到了大規模并行開發階段才發現,可能造成"程式員碰頭兒臨時決定"的情況大量出現,軟體品質必然将下降甚至導緻項目失敗。
其中,采用哪些現成架構、哪些第三方SDK、乃至哪些中間件平台,都應該考慮是否由軟體架構的開發視圖确定下來。圖6展示了裝置調試系統的(一部分)軟體架構開發視圖:應用層将基于MFC設計實作,而通訊層采用了某序列槽通訊的第三方SDK。
在說說限制性需求。限制應該是每個架構視圖都應該關注和遵守的一些設計限制。例如,考慮到"一部分開發人員沒有嵌入式開發經驗"這條限制情況,架構師有必要明确說明系統的目标程式是如何編譯而來的:圖7展示了整個系統的桌面部分的目标程式pc-moduel.exe、以及嵌入式子產品rom-module.hex是如何編譯而來的。這個全局性的描述無疑對沒有經驗的開發人員提供了實感,利于更全面地了解系統的軟體架構。
性能是軟體系統運作期間所表現出的一種品質水準,一般用系統響應時間和系統吞吐量來衡量。為了達到高性能的要求,軟體架構師應當針對軟體的運作時情況進行分析與設計,這就是我們所謂的軟體架構的處理視圖的目标。處理視圖關注程序、線程、對象等運作時概念,以及相關的并發、同步、通信等問題。圖8展示了裝置調試系統架構的處理視圖。
可以看出,架構師為了滿足高性能需求,采用了多線程的設計:
應用層中的線程代表主程式的運作,它直接利用了MFC的主視窗線程。無論是使用者互動,還是序列槽的資料到達,均采取異步事件的方式處理,杜絕了任何"忙等待"無謂的耗時,也縮短了系統響應時間。
通訊層有獨立的線程控制着"上上下下"的資料,并設定了資料緩沖區,使資料的接收和資料的處理相對獨立,進而資料接收不會因暫時的處理忙碌而停滞,增加了系統吞吐量。
嵌入層的設計中,分别通過時鐘中斷和RS232口中斷來激發相應的處理邏輯,達到輪詢和收發資料的目的。
軟體最終要駐留、安裝或部署到硬體才能運作,而軟體架構的實體視圖關注"目标程式及其依賴的運作庫和系統軟體"最終如何安裝或部署到實體機器,以及如何部署機器和網絡來配合軟體系統的可靠性、可伸縮性等要求。圖9所示的實體架構視圖表達了裝置調試系統軟體和硬體的映射關系。可以看出,嵌入部分駐留在調試機中(調試機是專用單闆機),而PC機上是常見的桌面可執行程式的形式。
我們還可能根據具體情況的需要,通過實體架構視圖更明确地表達具體目标子產品及其通訊結構,如圖10所示。
所謂本立道生。深入了解軟體需求分類的複雜性,明确區分功能需求、限制、運作期品質屬性、開發期品質屬性等不同種類的需求就是"本",因為各類需求對架構設計的影響截然不同。本文通過具體案例的分析,展示了如何通過RUP的4+1視圖方法,針對不同需求進行架構設計,進而確定重要的需求一一被滿足。
本文重點在于方法的解說,是以省略了對架構設計中不少具體問題的說明,同時本文提供的說明架構設計方案的模型也經過了簡化。請讀者注意。
Philippe Kruchten著,周伯生等譯. Rational統一過程引論(原書第2版). 機械工業出版社,2002
Karl E. Wiegers著,劉偉琴等譯. 軟體需求(第2版). 清華大學出版社,2004