談談UI架構設計的演化


談談UI架構設計的演化

經典MVC

在1979年,經典MVC模式被提出。

在當時,人們一直試圖將純粹描述思維中的對象與跟計算機環境打交道的代碼隔離開來,而Trygve Reenskaug在跟一些人的討論中,逐漸剝離出一系列的概念,最初是Thing、Model、View、Editor。后來經過討論定為Model、View和Controller。作者自言“最難搞的就是給這些架構組件起名字”。

因為當時的軟件環境跟現在有很大不同,所以經典MVC中的概念很難被現在的工程師理解。比如經典MVC中說:“view永遠不應該知道用戶輸入,比如鼠標操作和按鍵。”對一個現代的軟件工程師來說,這聽上去相當不可思議:難道監聽事件不需要類似這樣的代碼嗎?

view.onclick = ......

但是想想在70年代末,80年代初,我們並沒有操作系統和消息循環,甚至鼠標的光標都需要我們的UI系統來自行繪制,所以我們面對的應該是類似下面的局面:

mouse.onclick = ......
mouse.onmove = ......

當鼠標點擊事件發生后,我們需要通過view的信息將點擊事件派發到正確的view來處理。假如我們面對的是鼠標、鍵盤驅動這樣的底層環境,我們就需要一定的機制和系統來統一處理用戶輸入並且分配給正確的view或者model來處理。這樣也就不難理解為什么經典MVC中稱"controller是用戶和系統之間的鏈接"。

因為現在的多數環境和UI系統設計思路已經跟1979年完全不同,所以現代一些喜好生搬硬套的"MVC"實現者常常會認為controller的輸入來自view,以至於畫出model、view、controller之間很奇葩的依賴關系:

image

我們來看看Trygve Reenskaug自己畫的圖(這惡趣味的骷髏啊……):

image

值得一提的是,其實MVC的論文中,還提到了"editor"這個概念。因為沒有出現在標題中,所以editor聲名不著。MVC論文中推薦controller想要根據輸入修改view時,從view中獲取一個叫做editor的臨時對象,它也是一種特殊的controller,它會完成對view和view相關的model的修改操作。

控件系統

MVC是一種非常有價值的架構思路,然而時代在變遷,隨着以windows系為代表的WIMP(window、icon、menu、pointer)風格的應用逐漸成為主流,人們發現,view和controller某些部件之間的局部性實際上強於controller內部的局部性。於是一種叫做控件(control)的預制組件開始出現了。

控件本身帶有一定的交互功能,從MVC的視角來看,它既包含view,又包含controller,並且它通過"屬性",來把用戶輸入暴露給model。

controller的輸入分配功能,則被操作系統提供的各種機制取代:

  • 指針系統:少數DOS時代過來的程序員應該記得,20年前的程序中的“鼠標箭頭”實際上是由各個應用自己繪制的,以MVC的視角來看,這應當屬於一個"PointerView"的職責范疇。但是20世紀以后,這樣的工作基本由操作系統的底層UI系統來實現了。
  • 文本系統:今天我們幾乎不需要再去關心文本編輯、選中、拖拽等邏輯,對web程序員可以嘗試自己用canvas寫一個文本編輯框來體驗一下上個時代程序員編寫程序的感受。你會發現,選中、插入/覆蓋模式切換、換行、退格、雙擊、拖拽等邏輯異常復雜,經典MVC模式中通常使用TextView和TextEditor配合來完成這樣的工作,但是今天幾乎找不到需要我們自己處理這些邏輯的場景。
  • 焦點系統:焦點系統通過響應鼠標、tab鍵等消息來使得控件獲得操作系統級唯一的焦點狀態,所有的鍵盤事件通常僅僅會由擁有焦點的控件來響應。在沒有焦點系統的時代,操作系統通常是單任務的,但是即使是單一應用,仍然要自己管理多個controller之間的優先權和覆蓋邏輯,焦點系統不但從技術上,也從交互設計的角度規范化了UI的輸入響應,而最妙的是,焦點系統是對視覺障礙人士友好的,現在頗多盲人用讀屏軟件都是強依賴焦點系統的。

所以時至今日,MVC,尤其是其中controller的功能已經意義不大,若是在控件系統中,再令所有用戶輸入流經一個controller則可謂不倫不類、本末倒置。MVVM的提出者,微軟架構師John Gossman曾言:“我傾向於認為它(指controller)只是隱藏到后台了,它仍然存在,但是我們不需要像是1979年那樣考慮那么多事情了”

MVP

1996年,Taligent公司的CTO,Mike Potel在一篇論文中提出Model-View-Presenter的概念。

在這個時期,主流的view的概念跟經典MVC中的那個“永遠不應該知道用戶輸入”的view有了很大的差別,它通常指本文中所述的控件,此時在Mike眼中,輸入已經是由view獲得的了:

image

Model-View-Presenter是在MVC的基礎上,進一步規定了Controller中的一些概念而成的:

image

對,所以,不論你按照Mike還是Trygve的理解方式,MVP和MVC的依賴關系圖應該是一!模!一!樣!的!因為Mike的論文里說了“we refer to this kind(指應用程序全局且使用interactor, command以及selection概念的) of controller as a presenter”。presenter它就是一種controller啊!

image

把依賴關系畫成這樣也是醉了啊!不管你信不信我反正是不信啊!

標記語言和MVVM

隨着20世紀初web的崛起,HTML跟JS這樣標記語言+程序語言的組合模式開始變得令人注目。逐漸推出的Flex、Sliverlight、QT、WPF、JSF、Cocoa等UI系統不約而同地選擇了標記語言來描述界面。

在這樣的架構中,view(或者說叫控件,不但是從依賴關系上跟程序的其他部件解耦,而且從語言上跟其它部分隔離開來。

標記語言的好處是,它可以由非專業的程序員產生,通過工具或者經過簡單培訓,一些設計師可以直接產生用標記語言描述的UI。想要突破這個限制使得view跟其它部分異常耦合可能性也更低。

然而這樣的系統架構中,MVC和MVP模式已經不能很好地適用了。微軟架構師John Gossman在WPF的XAML模式推出的同時,提出了MVVM的概念。

WPF得MVVM正式說明了它的view的概念跟MVC中的view的概念的區別。這里簡單畫了一下:

image

在MVVM模式中,數據綁定是最重要的概念,在MVC和MVP中的view和model的互相通訊,被以雙向綁定的方式替代,這進一步把邏輯代碼變成了聲明模式。

結語

從經典MVC到MVVM,UI架構經過數次重大變遷,一些概念也在不斷變化,架構和底層環境互相影響、適配,我認為時至今日,經典MVC已經不再是UI架構的正常選項。

更糟糕的是,今天無數經過演繹的MVC實現(如backbone)和科普文,要么是原本作者概念已經很混亂,摻雜私貨,要么為了適配現代的標記語言和控件模式,自己修改了經典MVC中的一些概念和耦合關系。實際上今天MVC已經沒法作為一種交流的標准詞匯了。

寫此文,希望大家能了解些歷史上的發展歷程,莫被不嚴謹的文章誤導。其實本文的相當多觀點也是經過演繹的,所以我附上所有原始文獻鏈接,希望大家看了以后能有自己的判斷:)也歡迎大家據此指出我理解的錯誤之處。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM