l

2016年11月23日 星期三

軟體架構模式(3):Model-View-Controller

Nov. 23 09:27~11:20

擷取

▲圖片節錄自《POSA 1》

 

今天介紹的是鄉民們聽到耳朵都快長繭的Model-View-Controller(MVC)模式,看看《POSA 1》書中如何描述它。

Model-View-Controller

MVC模式將互動系統切割成三個元件:Model包含核心功能與資料、View顯示資訊、Controller處理使用者的輸入。View和Controller合在一起構成使用者介面,並透過異動通知機制確保使用者介面與model維持一致性。

Context:你所設計的互動應用系統包含靈活的人機介面。

Prooblem:如何分解一個系統?

Forces

  • 相同資訊以不同的方式顯示在不同的視窗或使用者介面上。例如分別用長條圖與圓餅圖顯示總統候選人的支持度、用數位與類比方式顯示目前溫度。
  • 資料顯示與應用程式行為必須要立即反應資料操作結果。例如溫度改變必須立刻被反應在使用者介面上,或是使用者透過介面調整電腦時間必須被寫回電腦系統。
  • 改變使用者介面應該要很容易。
  • 支援新的 "look and feel" 標準或移值使用者介面不應該影響到應用程式核心程式碼(model可以繼續使用)。

Solution:將互動系統切割成三個範圍:processing(Model)、output(View)、input(Controller)。Model封裝核心資料與功能,並且獨立於特定的顯示方式與輸入行為。View負責顯示Model的資料,一個Model可以包含多個View。每一個View有一個Controller用來接收輸入(例如滑鼠或鍵盤事件),並將其轉換成對Model或View的呼叫。

區分Model與View/Controller讓我們可以使用多個View來顯示相同Model。如果使用者透過某個View的Controller改變Model的資料,所有其他相依於該Model的View將會收到Model關於資料異動的通知,如此一來這些View便可從Model接收異動的資料並用來更新自己所顯示的資訊。

Resulting Context

  • 可以使用多個View來顯示相同的Model。
  • 顯示相同Model的多個View之間可以保持同步。
  • 可插拔的View和Controller。因為View/Controller和Model分離,所以可以改變用來顯示Model的使用者介面,甚至可以在runtime做出這樣的改變。
  • 當系統轉移到其他平台的時候,可以只更換使用者介面而繼續保留Model。
  • MVC可以被使用於應用程式框,減化互動程式的開發。
  • 增加複雜度。嚴格區分MVC有時候會增加系統複雜度,例如在menu或簡單的text元件上套用MVC可能就變成殺雞用牛刀。
  • 當Model改變的時候可能會造成過度的異動通知,例如也許不需要通知最小化的視窗去去更新資料。
  • 雖然MVC區分了Model、View、Controll,但View和Controller其實是緊密偶合的元件,很難各別被重複使用。
  • View/Controller和Model之間有緊密的耦合關係,如果Model改變很可能會造成View/Controller也跟著改變。
  • 更新View所造成的低效率資料存取。為了更新資料,View可能需要呼叫Model好幾次以獲得所需資料。不必要的讀取未異動資料將降低執行效能。
  • 移值到不同使用者介面平台存在對於View與Controller不可避免的修改。「理論上」和使用者介面有關的部分都被封裝在View和Controller身上,移值到不同的使用者介面應該只要替換View和Controller。實際上View和Controller有時會包含一些與平台有關的程式碼,在這種情況下如果系統未來有移值的需求則需要進一步將這些與平台相依的程式碼封裝起來。
  • MVC與圖形使用者設計工具的整合。不同的圖形使用者設計工具可能有它自己的框架,並不一定與MVC相容。例如有些工具會把輸入事件自動轉派給特定的callback function,因此就不需要額外在提供一個Controller元件給View。

Known Uses:Smalltalk、MFC、.Net MVC、Spring MVC。

***

在實作上MVC有很多變形,以《POSA 1》書中為例,View和Controller都實作Observer介面,都可以接收到Model的資料異動通知,也都有機會去更新View。下圖是《POSA 1》書中對於View和Controller的責任描述,其中更新資料是View的主要責任(implements the update procedure),對Controller來說則是次要責任(implements the update procedure, if required)。有一種作法是讓View和Model自動綁在一起,因此使用者就不需要去實作更新View的程式。另一種作法則是減少View和Model之間的耦合,讓Controller全權負責View的資料更新。還有另一種極端則是把一個視窗中所有View的Controller都集中到一個稱為Presenter的元件身上,讓它集中負責View的更新與輸入,而View只負責最簡單的顯示,這種模式稱為Model-View-Presenter(MVP)。

MVC還有其他的變形,以後有機會再介紹。

擷取

▲View和Controller的CRC卡,節錄自《POSA 1》

***

友藏內心獨白:MVC是互動應用程式的基本款架構。

沒有留言:

張貼留言