前言:
架構(Architecture)一詞,非常之難解釋。
若真要一言以蔽之,那麼,可以說,”架構” 是一種整體觀,需要保持從各角度看待架構時,仍有一致性與調和的觀點。
對 ”架構” 要能有充分的理解與認識,至少要能確實瞭解與體會下列幾個與架構至為關鍵的意涵與術語,包括了:整體、觀點(View),包括巨(Macro)觀與微(Micro)觀、焦點(Focus)、層次(Layer)、廣度(Boundary)。
擔任軟體架構師(Software Architect)必備的素養,即在於:觀照整體的能力。
經常我在輔導許多軟體公司的專案開發與教育訓練時,發現到與開發團隊對 “架構” 一詞的認知與定義大不相同。我發現到,大部分的 IT 技術開發人員,所表達出來的架構,是比較偏向於實體層次如 .NET, J2EE 的 IT 技術層次。不是不對,而是 IT 實體層次僅是架構的觀點之一,並不足以代表整體的架構觀。
我想試著利用以上述幾個術語來解釋 “架構”。畢竟,架構的設計,牽涉到相關於設計中系統的議題與範圍太廣了,包括:團隊開發的共識、開發流程(Development Process)的制訂,分工與外包(Outsourcing)控管、系統的彈性、延展(Scalibility)與維護性等。
金剛經有云:「凡所有相,皆屬虛妄,見諸相非相,即見如來」。
“相”,是被具化、可以看得到的形,如同軟體模型,是被具化的產出(Artifact),也就是 “相”。而 “如來”,是不著相的,架構即為如來,所以架構也可以說是一種空、無。
問題來了,既然不著相,你又如何知道何為正道,何為如來?
佛教禪宗有個「以指標月」的譬喻:對於一個從不來不知月亮為何物的人,在蒼茫的星空中,不知那一個叫做月亮,這時候就需要一個認識月亮的人,用手指著月亮說:「那就是月亮」。
同樣的道理,你又能如何瞭解甚至來驗證架構(如來)的正確性呢?
有經驗的架構師(Architect),以各種不同的角度(以上所涵蓋的幾個術語),建構各類型的軟體模型,來看待並解釋「架構」。如同「以指標月」一般,對架構有深一層體會的架構師,會以導師(Mentor)的角色,利用各種工具來具化產出,以引導軟體設計師認識「架構」。
所以,UML, 程式碼等只是個標示工具,真正的「架構」是要靠自己去體會的。
觀點(Viewpoint)
我想首先以 “觀點(Viewpoint)” 一詞來解釋架構。
要能具軟體架構的整體與協調性,最起碼要能有三個觀點:
ˇ 需求面的觀點
ˇ 結構面的觀點
ˇ 實做面的觀點
● 需求面的觀點:
需求(Requirement),代表著的是系統外部的觀點,也就是從 “Actor” 的角度來看待系統,系統所該提供的功能(Function)。
我會建立使用案例模型(Use Case Model),來代表需求面的觀點,每一個使用案例,即代表系統所該履行的功能。
使用案例模型的建立,我會視系統規模的廣度,來決定是否建立企業使用案例(Business Use Case Model)模型與系統使用案例模型(System Use Case Model)。
不以使用案例模型來代表需求面的觀點,未嘗不可。例如,利用如 XP(Extreme Programming) 的使用者陳述(User Story)來紀錄系統的功能點(Functional Point),當然可以更形簡化需求面的陳述。只是,我個人是偏好於利用視覺化來建立各種觀點的模型,感覺會更有助於對整體系統的瞭解。尤其是,我經常以 “套件圖(Package)”,表達在使用案例圖內,子系統與子系統之間範圍的界定與溝通。
● 結構(Structure)面的觀點:
系統的結構設計,可以說才是決定系統的彈性、延展、效能、穩定等主要成敗因素。
國內軟體專案的開發,絕大部分並不重視系統的結構設計。主因在於專案開發時程偏短線的不合理、軟體人員對結構設計未能俱足抽象與實務並重的技能,以及內部的結構是客戶所看不到,並且短期無法能感受到的。專案開發因重視短線立即性的效果,所以反而以功能需求面、使用者介面(UI)為主要的開發重點。
這如同購買房子一樣,一開始因為樣品屋美輪美奐的室內佈置(UI),以及附贈許多的家具、生活用品(功能),卻忽視掉房屋的結構設計。短期感受不到問題,住久後才逐漸顯現出如漏水、海砂屋甚至因鋼架的偷工減料而導致強烈地震一來即崩垮的慘劇。
軟體的結構模型,至少有兩個主要的產出:類別(Class)設計圖與循序(Sequence)圖。
類別圖表達的是系統的內部靜態結構;循序圖表達的是系統內部元素(稱之為物件比較理想)之間,為完成某一交付的任務(系統功能),物件之間互動合作的動態行為。
傳統的軟體結構分析與設計,會以為主要的工作是建立資料庫的 E-R(Entity-Relationship) 模型。這該算是靜態結構設計的一種退化解,雖然 E-R 圖是以問題領域(Problem Domain) 的術語作為分解的依據,這與類別圖設計的分解思維是一致的。不過最主要的問題,仍在於 E-R 圖的分解元素沒有自主性的行為(Behavior)能力,把行為抽離出來而分散至 Form Script, Web Page, Stored-procedure …, 甚至亂分一番,隨便實做某個物件,把演算邏輯 “塞” 進去就號稱為物件導向設計。
行為的分散,造成系統彈性與維護的困難性,是注重以 E-R 資料模型為結構設計主體的問題點。類別圖(Class Diagram),回歸至本質面,把資料與行為有效歸納至所該承擔的物件上。類別圖的設計最困難與謹慎之處,即在於如何有效分派責任(Responsibility Assign)至物件上。
結構的設計,若以層次(Layer)之分,又分為高階抽象的領域模型,與細部、平台面相依的軟體規格模型。層次的問題,我會以另外一個主題:從層次來解釋架構時,來討論之。
越是高階、抽象的結構模型,會比較偏向於 “本質面”,當越能抽至最接近本質面的那一層,結構越為穩定。越接近本質面的那一層,其呈象反而越是簡單(Simple),但是,要能呈現出簡單,本身卻不簡單,是最為難之分析、設計的。
理由是,結構設計師需要非常高度的抽象理解能力。抽象能力的培養,講究悟性,左、右腦需能平衡協調,絕非純左腦邏輯的分析,也無法利用所謂的方法論(Methodology),以所謂的 “規則” 來套用。這是 “純(Pure)” 軟體設計的修練,起碼要花上 5~10 年以上(最保守的估計),培養個人的反思與創意思考能力,來鍛鍊對軟體設計的基本功夫。
● 實做面的觀點:
程式碼(Source Code) 是實做最主要的產出,也可以說是最直接、有效的產出。因為,無論你的設計圖作得多棒,卻很難以工具來驗證、測試其正確性。但是,程式碼,經過語法檢查、編譯後,能不能執行,馬上就可以知道,並且可以透過各種的測試機制,來測試包括功能、效能、容錯(Fault Tolerance) ...等各類的測試項目。
從實做面的觀點,我個人一直大力主張要能針對系統功能作測試自動化,而不要僅流於紙張上的測試案例。功能絕對會善變,功能一變,測試程式碼就必須得跟著改變,否則無法通過自動化的測試。
這非常重要,因為會直接影響到 “驗收” 這一環節。這裡我太認同 XP 其中之一的實務;測試先行(Test First)。由客戶撰寫測試的情節(Scenario)與提供測試相關的數據;開發團隊負責撰寫測試程式碼。
使用者接受度測試(UAT, User Acceptance Test),是可以透過撰寫功能測試程式碼來達到自動化的測試,不過,卻無法測試程式碼的結構內涵。
結構的測試,更是一個重要的議題。有太多的軟體開發單位,是先寫程式碼,再反轉回(Reverse)設計圖,把設計圖當文件(Document)交差了事。這很危險,脆弱的結構,是導致系統複雜難以維護,以及無法應變的主因。
我會利用如 Together, EA(Enterprise Architect) 等 UML 工具,幫程式碼照 “X” 光,檢驗其脈絡。反轉程式碼,呈現視覺化的模型後,最重要的是檢查元素的相依性(Dependence),從巨觀包括子系統、模組,至微觀包括套件(Package)、元件(Component)等,是否有違背原先所承諾客戶的結構設計。
圖、範例-利用 Borland Together 檢視套件與類別的相依性關係(縮略圖,點擊圖片鏈接看原圖)
補充— RUP 的 4+1 觀點(View)
以上三個觀點應該算是最簡化的了,是我認為最起碼該具備的,才有可能從不同角度,仍能以一致、整體性,來看待架構。此外,這裡再補充,RUP 對架構的解釋,它以是所謂的 “4+1 View” 來說明架構。
RUP(Rational Unified Process) 的開發模式,係以架構為中心(Architecture-Centric)的流程,當組織或團隊對架構的呈現方式已經取得共識,認為它符合手上的問題後,下一個議題就是學會架構設計的流程與規劃(Architectural Design Process)。
RUP 利用從五個架構觀點的方式,來簡化對架構的描述(或稱之為抽象化)。每一個觀點,會涵蓋了與之相關特殊的考量點,而忽略跟該觀點無關的東西。對每一個觀點,需要清楚找出:
- 觀點 – 我們希望專注的考量點和關係人。
- 觀點中所捕捉並呈現的元素和它們之間的關係。
- 建立觀點元素與其它觀點元素之間的關係。
- 建立觀點的最佳流程。
如下圖,RUP 所建議五個觀點方式。而其中,係以使用案例(Use Case)的觀點來驅動(Drive)其它四個觀點,所以,又稱之為 4+1 架構觀點的模型。
圖、RUP 4+1 架構觀點的模型(摘錄自 Philippe Kruchten “The 4+1 View Architecture”)
(縮略圖,點擊圖片鏈接看原圖)
● 邏輯觀點(Logical View)
此架構觀點專注在系統的功能性需求(Functional Requirement),也就是說,系統該為終端使用者(End-User)做到的事。
邏輯觀點是設計模型(Design Model)的抽象概念,用來找出在分析與設計階段時的類別(Class)、子系統(Sub System)、主要套件(Package)。
例子包括訂購、訂購細項、顧客、產品和產品型錄等套件。
● 實做觀點(Implementation View)
此架構觀點利用套件與階層(Layer)或組態管理(Configurement Management)來描述開發環境中靜態軟體的模組(Module)、原始碼(Source Code)、資料檔、元件(Component)、可執行(Executable)碼和其它工作成果等組織。
它專注再容易開發、軟體資產管理、可再利用性(Reuse)、外包和客製化元件等議題上。
例子包括訂購子系統的原始程式碼。
● 程序觀點(Process View)
此架構專點專注在執行期間(Runtime),系統的並行性(Concurrency),包括工作(Task)、執行緒(Thread)或程序(Process)、交易(Transaction)、安全性(Security)以及資源(包括資料庫連線與物件個體數)管理等範疇。
程序的觀點,會視專案規模的大小,而有不同的應對與處理方式。
例子包括訂購系統如何處理超過同時上線客戶的人數超過 5000 人,仍能包持系統的穩定度與效能(如3秒內完成訂購的交易)的處理。
● 配置觀點(Deployment View)
此架構觀點展現不同的可執行(Executable)和其它執行時期(Runtime)元件,如何把它們配置(Deploy)在基本平台或運算的節點(Node)上。
此一觀點,會處理配置、安裝和效能等議題。
例子包括在 Windows 2000 上,安裝了 IIS 以及 .NET Framework、MTS(Microsooft Transaction Service)等應用伺服器,然後在其內配置了訂購系統,並連接另一台同為 Windows 2000 系統、安裝了 SQL Server 2000 的資料庫系統。
透過 “以使用案例為驅動” 的架構觀點,更能清楚瞭解在每一個流程的核心工作流程,其主要的設計模型產出與產出之間的關係。參考如下圖。
圖、”流過” 各種模型的使用案例(摘錄 “The Rational Unified Process An Introduction 2nd))
(縮略圖,點擊圖片鏈接看原圖)