MVC方式通常在Smalltalk中用於建立用戶接口。通過對MVC中蘊藏的設計模式可以幫你理解我們所說的“模式”的含義。
MVC包括三類對象,Model是應用對象、View為其屏幕表示、Controller定義了對用戶輸入的處理(反應)方式。在應用MVC方式以前,通常將這三個對象的功能合到了一起,應用MVC分離了它們,為設計提供了靈活性和可重用性。
MVC通過在view和model之間建立Subscribe/Notify協議,分離了view和model對象。View對象必須保證它的表示反應了model對象的狀態,當model對象的數據改變時,model對象通知(Notify)view對象,作為對這一行為的反應,每個view對象得到了一個做出更新的機會。這種方式使得可以將多個view對象為一個model對象提供不同的表示。你也可以為model對象建立新的view對象,而不用重新編寫model。下圖演示了一個model和三個view:
從表面看,這一例子反應了一個將view和model分離的設計。然而,這種設計適合一類更通用的問題:減少對象之間的藕和性,這樣,當一個對象改變時,將不會影響到另外的對象,甚至不需要知道另外的對象的實現細節。這種更通用的模式將在Observer模式中來描述。
MVC方式的另一個特點是,view對象是可嵌套定義的。例如,button的控制板可由一個包含嵌套button view對象的復雜view對象來實現;對象觀察器的用戶接口可由能重用於調試器的嵌套view對象組成。MVC方式采用CompositeView類(View的子類)來支持嵌套view,其行為與view對象的行為一致,可用於view對象能使用的任何場合。
於是,我們又可以把這種對待composite view就像處理其一個組件的方式看成一種設計(方式)。同樣的,這種設計可抽象出另一類更通用的問題(的解決方式):我們在某種情形下將對象分成組,並且處理一個組就像對待對象個體。這種方式我們用Composite設計模式來描述。它允許你建立類的層次,在這一層次下,有些子類定義原始對象(如Button),而其它的類可以定義合成對象(CompositeView),合成對象可將原始對象裝配成更復雜的對象。
同樣,MVC也可改變視圖類(view)對用戶反應的方式,而不用改變其可視化表示。你可能想改變其對鍵盤響應的方式,如,使用彈出菜單代替命令鍵。MVC將這種反應機制封裝為控制對象(Controller)。控制器有一個類層次,易於實現從一個已存在的控制器建立出一個變種—一種新的控制器。
視圖(view)對象通過某一控制器對象的實例(instance)來實現特定的響應策略。為了實現不同的策略,可以簡單的使用不同的控制器實例來替換當前的實例。甚至可以在運行時來改變視圖的控制器,以改變視圖對象對用戶輸入的響應(策略)。例如,一個view對象可置為disabled,即對用戶的輸入不做任何響應。要達到這一目的,僅僅只需讓控制器忽略所有input事件。
這種視圖—控制器關系即是Strategy設計模式的一個典型例子。所謂Strategy即這樣一個對象,它表示了一種算法。這在你想要替換算法(無論是靜態替換還是動態替換)時特別有用,而這樣的算法可能有許多的變量、或者擁有復雜的數據結構。
MVC中也使用了別的設計模式,例如,使用Factory Method模式來描述視圖的默認控制器類;采用Decorator模式來為視圖增加滾動條等。但在MVC中的主要模式是前述的Observer、Composite、和Strategy設計模式。