.Net企業級應用架構設計之表現層設計

綜述

如果沒有用戶界面,哪個程序都不能運行。哪怕是中間層代碼堪稱完美,用戶也無法使用到。很多架構師不太重視表現層,僅將表現層作爲業務層和數據訪問層完成後的一個細節處理。但實際上,用戶界面、業務邏輯和數據訪問代碼在任何一個系統中都是同等重要的。你的態度、偏好和自身的專業技能決定了你爲每個層制定的“優先級”,也導致了你對各個層的關注順序。

實際的開發中,表現層經常是系統中最後開發的一部分,且非常依賴於VS等開發工具所提供的功能。表現層很大一部分工作可以由功能強大的高級工具完成,不過這些強大工具的出現可能會讓架構師和開發者不太重視表現層的良好設計。表現層的實現可以非常簡單,也可以非常複雜。因此在開始時使用快速應用程序開發(RAD)工具、嚮導、小工具直接和數據庫綁定,但是同時你要對你現在的做法有清醒的認識。若表現層逐漸變得複雜起來,即變成一個圖形化的表現層加上很多應用程序的邏輯,那麼就應該使用規範和模式來進行整理,就像在業務層和數據訪問層的做法一樣。

表現層由兩個主要組件組成:用戶界面和表現層邏輯。用戶界面給用戶提供了實用程序的接口,程序的所有行爲都是通過用戶界面中的圖形化元素或者文本元素暴露給用戶。這些元素用來提供信息、建議下一步操作並通過鍵盤和鼠標等輸入設備捕獲用戶活動。用戶在用戶界面上進行的任何操作都將成爲表現層的另一個組件,即表現層邏輯的輸入。表現層邏輯是指所有用來處理將要顯示的數據的邏輯,加上將用戶輸入轉換爲後臺系統的命令的邏輯。換句話說,表現層邏輯將負責中間層和UI之間數據流的交互。

表現層職責

如果若讓軟件工程師列出表現層的指責,那麼你一定會聽到如下的描述:驗證、格式化、添加樣式、和可用性等。不過可用性更像是一個屬性而不是職責,且諸如驗證、添加樣式和格式化的特性更應該屬於UI組件,而不是表現層。

作爲設計表現層的架構師,你應該站的更高一些,至少在最初時應該這樣。表現層的職責應該從更高的角度考慮,即不依賴於物理UI、較高可測試性和不依賴與數據模型。

不依賴於圖形化元素:圖形化元素組成了應用程序的用戶界面,用戶將看到這些組件並進行交互,藉此將命令和信息傳遞給後臺系統。但是表現層必須保證圖形化用戶界面的任意修改都不會影響到數據流和表現層邏輯。只要變化屬於純粹的圖形化修改,那麼表現層都必須支持以透明的方式對待。現實的例子就是微博、博客、CMS等能切換主題樣式和佈局的用戶界面系統。

不依賴於UI技術:表現層必須不依賴UI技術和平臺,這個需求更難實現,且有時候無法做到完全不依賴,或許應該說盡量不依賴UI技術。一個很常見的需求是系統需要支持很多表現層,例如:Web、移動設備、Windows等。在需要讓同一個功能的用戶界面支持多種不同的UI技術和平臺時,設計良好的表現層可以讓開發者儘可能的重用現有的代碼。期待100%的重用很難做到,因此將目標定位“最大化代碼重用”要比“完全代碼重用”更加現實。

支持測試:抽象是表現層提高可測試性的關鍵工具,抽象可以通過分離關注點實現,即將視圖和表現層邏輯分開。

不依賴於數據模型:無論中間層選擇何種模型,都不應該影響表現層,或者說表現層應該儘可能的不受到影響。理論上,每個從表現層調用到應用程序邏輯中的方法都需要一對輸入和輸出的數據遷移對象。考慮到這些,我們會限制數據遷移對象的使用,僅將其用在系統最可能發生變化的地方。在表現層的特定情況下,讓其與數據模型之間存在一些依賴是可以接受的,不過這樣做必須是因爲可以帶來明顯性能或者維護上的優勢。

用戶界面的職責

一般來說架構師不直接參與圖形化界面的設計細節中,架構師的主要職責是保證產品滿足了所有的重要質量特性,特別是可用性和可訪問性。表現層邏輯中最棘手的部分就是爲表現層中的每個視圖設計出抽象,視圖的抽象將定義視圖中暴露出哪些輸入和輸出的數據。表現層邏輯的最終目標是確保視圖中的數據可以正確的流入 / 流出。在所有項目干係人都確認了每個視圖的公開接口以後,兩個團隊可以同時開發。

每個組成用戶界面的視圖都有其自身的職責,這些職責大多也儘可能確保表現層易於使用爲主。

實時的數據顯示:用戶界面的職責之一就是將數據顯示給用戶,數據包括普通信息、提示、以及應用程序操作的響應。良好設計的用戶界面要給用戶提供正確格式化的數據,並以可視化的方式顯示出來。格式化數據以便用來顯示的具體實現位置會有所不同,這取決於表現層設計中選用的模式。大多數時候這部分操作位於表現層邏輯中,不過也有些將格式化和顯示邏輯放在用戶界面中功能強大的控件中完成。

舒適的數據輸入:用戶界面時將用戶數據輸入至系統的地方,一個好的表現層將提供輸入格式規則並提供使用合適的輸入控件,讓用戶可以得心應手地輸入數據。從這個角度考慮,富控件和拖放有很大的優勢。此外,選項卡也可以將複雜的功能分組,讓用戶僅關注當前的這一部分東西。謹記所有的用戶輸入都是邪惡的,因此用戶界面必須要提供初步的驗證功能。雖然UI級別的驗證還不夠完備,不過驗證最好從這裏就開始。

總體外觀:應用程序的外觀和感覺是指用戶在使用應用程序時的體驗和其總體外觀的主要特徵。一般來說,將要給大衆使用的應用程序都要有精緻的用戶界面,因爲軟件的一個目的就是抓住用戶的注意,給用戶留下好的印象。對於公司內部的程序來說,其界面傾向於功能實現,而不是視覺效果的震憾。

表現層的常見誤區

在開始討論設計模式之前,先介紹幾個表現層相關的常見誤區。

表現層開發過於依賴RAD工具:VS給開發者帶來了一整套的實用工具,似乎暗示開發者不要浪費時間在設計和分離關注點上,這當然也是RAD概念的自然產物。直接雙擊按鈕寫代碼方便快捷,但對於大型企業級系統來說,RAD並不是一個理想的表現層開發選擇。建議將VS作爲快速UI設計器使用,而不是快速應用程序開發工具。VS及其所有RAD特性都在不停誘導我們在各種情況下使用,不過某些時候應該對它視而不見,杜絕點選的操作,而去手工編寫更多代碼。無節制的濫用RAD開發模式,會讓你創建出很多自治的視圖。所謂自治視圖是指一個類來編寫用戶界面的狀態和其中的所有行爲。自治視圖已經不再流行,最主要原因是難以測試。

表現層的邊界:表現層的負責程度應該僅由可伸縮性和性能需求決定。同時表現層也應該僅包含屬於表現層的邏輯,或許再加上一些混合或重複的少許經過你仔細權衡,並完全意識到其存在的業務邏輯。更要命的是,用戶界面相關的各種便利設施不停的誘惑開發人員將一些本不屬於表現層的代碼包含其中,這個問題在絕大多數項目裏面可以看到。UI必須與代碼隔絕,代碼也必須分層實現,高度遵守分離關注點原則。

用戶得到的就是你想要的:當你在使用聲明式而不是命令式編程時,也就將某些職責交給了另外一層的代碼來完成,這一層的代碼你無法控制。在開發中,將某些功能委託給第三方將提高開發速度,不過也需要保證的是用戶能夠精準得得到你所希望得到的東西。

表現層的演化

將表現邏輯和業務邏輯分離僅僅是良好設計的第一步。表現層邏輯的內部組織依賴於所選用的UI模式。歸根到底,表現層模式有3個主要分類:模型-視圖-控制器(MVC)、模型-視圖-展示器(MVP)、和PM。很多模式都是這3種演化而來,例如Model2演化自MVC,MVVM演化自PM。

MVC起源於完全面向對象的環境,它簡化了對用戶界面的測試,儘可能的將代碼從視圖中移走也助於代碼更加結構化,並在邏輯上分區。MVC要儘可能的被動,這意味着視圖應該僅僅負責處理將內容呈現給用戶。在MVC實現中,控制器將通過執行被觸發的操作來更新模型。隨後模型通知視圖其狀態發生了變化。視圖和模型是通過觀察者模式綁定到一起的。在觀察者模式中,主動方將在發生變化時通知觀察者。隨後,試圖從模型中讀取當前的狀態並進行相應的更新。MVP天生就比較複雜,僅適合於企業級應用程序或那些有着足夠複雜性、需要嚴格的模式和策略保證的項目中。

MVC模式兩個很大的不足。一個是模型需要與視圖通信,從而告知模型狀態的變化。另一個是視圖會隱式地對模型有所瞭解。MVP是MVC的一個衍生模式,力求讓視圖、模型和控制器三者能更好的彼此分開。可以說MVP是MVC的改進,原因有3個,視圖並不瞭解模型、展示器將忽略視圖中使用的具體UI技術、視圖可以被模擬,以便測試。MVP的核心就是將視圖和控制器的交互方式嚴格確定下來。在MVP中,控制器的名字改成了展示器,所以其核心價值在於規定了視圖和展示器之間的交互過程。MVP中視圖應該儘可能簡單、被動,不過這個僅存在於理論之中,實際上,一個完全被動的視圖非常難以編寫維護,甚至會給展示器帶來很多麻煩。軟件複雜性守恆定律說明,軟件系統中的複雜性是守恆的,可以從一層中轉移到另一層中。這就是說,表現層邏輯的總量保持固定,而你所能做的僅僅是決定架構上將其放在什麼位置。根據軟件複雜性守恆定律,從視圖中減少的複雜性將移動到其他層中,此處就是展示器。被動視圖將不可避免的帶來更加複雜的展示器,選擇被動視圖其實就是選擇高可測試性,同時帶來展示器類中的高複雜性。展示器這個名字可以更好的描述負責處理用戶操作的組件,展示器將用戶請求“展示”給後臺系統,隨後再把響應“展示”給用戶。展示器位於視圖和模型之間,它從視圖中得到用戶輸入並將命令傳遞給下面的模型。隨後展示器得到操作結果,並通過視圖提供的結構更新視圖。

PM模式和MVP沒有什麼很大差別。把它看作MVP的另一種變體,特別適合於複雜、功能豐富的用戶界面。在Windows平臺上,PM非常適合使用WPF和Sliverlight開發的程序,微軟公司也這樣推薦。若你想在Windows窗體、WPF或Sliverlight中需要比.Net內建UI更強大一些的功能,則可以使用MVP模式。若你在WPF/和Sliverlight中經常使用雙向綁定,那麼可以考慮PM模式,在WPF中這種模式也叫做MVVM。

小結

實際上,表現層的重要程度不亞於業務層和數據訪問層。沒有中間核心行爲的表現層即使再炫目也沒用,不過若沒有表現層與之配合,哪怕是再強大的中間層也無法滿足用戶需求。

相關博客:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章