PureMVC(AS3)剖析:開篇
緣起 |
自從事flash webgame開發起,3個項目都使用到了MVC模式:1個自己構建的MVC沒有使用外部框架;2個使用的PureMVC框架。對PureMVC也有了一定的深度的認識,是時候來總結、吐槽下。現在網上已經流傳很多關於PureMVC的資源,但是總覺得深度不夠,故有了現在這個系列,我盡量帶着自己的思考深入的介紹PureMVC,同時也能引起大家的思考。這里我並不是一味的說PureMVC有多好,它也有值得質疑和使用不爽的地方。
MVC思維
要了解PureMVC框架,首先得有MVC的思維方式,用MVC的思想去思考問題,分解需求、實現需求。MVC背后的核心思想是:
代碼重用(code reusability)、關注點分離(separation of concerns,SoC)
MVC思維圍繞這兩點轉,下面舉個例子說明。對於一個游戲或軟件來說,給人的第一感覺就是界面(視圖View),它展示了一些數據等信息給用戶。這些界面上的數據可以存儲在視圖View屬性或定義的變量中,如游戲中用戶信息欄中顯示玩家的等級、經驗、昵稱:
圖:玩家信息欄界面
這樣數據跟視圖綁定在一起,其它界面視圖(玩家詳細信息欄)想要等級、經驗、昵稱等數據需要訪問玩家信息欄界面,又或者從后台重新拉取。
圖:玩家詳細信息界面
這里違反了“代碼重用和關注點分離”思想,需要把數據獨立出來保存在一個與View無關地方模型(Model),多個視圖可以共用一份數據。這樣代碼即可重用,關注點也實現了分離, View只需要關注如何展示信息, Model只需要關注數據本身及相關邏輯。
上面達到了界面和數據分離之后,但是思考這樣一個過程:用戶操作了View需要更新Model,同理Model改變了需要更新View的顯示,該如何去做?可能會想到用戶操作View時直接調用Model接口去更新數據,這時其他共用這個Model的視圖View如何同步更新又是一個問題。Model改變了數據,直接調用View接口更新顯示的話,它必須要知道所有的共用這個模型Model的視圖View。
這樣視圖View與模型Model就不能達到徹底的“代碼重用和關注點分離”。MVC的指導思想就是把這個部分代碼獨立出來稱為控制器Controller。模型和視圖從此也只關心控制器,而不關心對方。他們的代碼都是處理自己的事情,別人的事情全部交給控制器去辦,這使得他們自己的功能也非常獨立,減少了需要考慮的要素。
在這之后,三者的關系只存在簡單的調用代碼。那么為了能夠徹底的分離和解耦,就可以將調用代碼改為事件或者其他的動態形式(如發布/訂閱、依賴注入等等),常用的MVC框架都實現了這樣的功能。
圖:MVC結構圖(實線——>表示依賴;虛線---->表示事件/通知等)
l 模型(Model):“數據模型”(Model)用於封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法。“模型”有對數據直接訪問的權力,例如對數據庫的訪問。“模型”不依賴“視圖”和“控制器”,也就是說,模型不關心它會被如何顯示或是如何被操作。但是模型中數據的變化一般會通過一種刷新機制被公布。為了實現這種機制,那些用於監視此模型的視圖必須事先在此模型上注冊,從而,視圖可以了解在數據模型上發生的改變。(比較:觀察者模式(軟件設計模式))
l 視圖(View):視圖層能夠實現數據有目的的顯示(理論上,這不是必需的)。在視圖中一般沒有程序上的邏輯。為了實現視圖上的刷新功能,視圖需要訪問它監視的數據模型(Model),因此應該事先在被它監視的數據那里注冊。
l 控制器(Controller):控制器起到不同層面間的組織作用,用於控制應用程序的流程。它處理事件並作出響應。“事件”包括用戶的行為和數據模型上的改變
請大家記住“MVC思維“及上面這些描述,后面還會引用這些。
PureMVC框架
PureMVC框架的目標很明確,即把程序分為低耦合的三層:Model、View和Controller。降低模塊間的耦合性,各模塊如何結合在一起工作對於創建易擴展,易維護的應用程序是非常重要的。
在PureMVC實現的經典MVC元設計模式中,這三部分由三個單例模式類管理,分別是Model 、View和Controller。三者合稱為核心層或核心角色。PureMVC中還有另外一個單例模式類——Façade,Façade提供了與核心層通信的唯一接口,以簡化開發復雜度。
圖: PureMVC設計示意圖(摘自官方網站)
從設計圖中可以清楚看到,除了核心層、Façade之外,還有Mediator、Proxy、Command。
l Proxy: Model 保存對 Proxy 對象的引用,Proxy 負責操作數據模型,與遠程服務通信存取數據。
l Mediator: View 保存對 Mediator 對象的引用 。由 Mediator 對象來操作具體的視圖組件,包括:添加事件監聽器,發送或接收 Notification ,直接改變視圖組件的狀態。這樣做實現了把視圖和控制它的邏輯分離開來。
l Command: Controller 保存所有 Command 的映射。Command 類是無狀態的,只在需要時才被創建。Command 可以獲取 Proxy 對象並與之交互,發送 Notification,執行其他的 Command。
為了徹底解耦,避免直接的函數調用,PureMVC使用觀察者模式(發布/訂閱)的形式傳遞消息。PureMVC 的通信並不采用 Flash 的 EventDispatcher/Event,因為PureMVC 可能運行在沒有 Flash Event 和 EventDispatcher 類的環境中,它的通信是使用觀察者模式以一種松耦合的方式來實現的。
你可以不用關心 PureMVC 的 Observer/Notification 機制是怎么實現的,它已經在框架內部實現了。你只需要使用一個非常簡單的方法從 Proxy, Mediator, Command 和 Facade 發送 Notification,甚至不需要創建一個Notification 實例。
下面是我對PureMVC的理解畫的設計示意圖:
圖: PureMVC另種示意圖
參考文章
[1] PureMVC官方網站:www.puremvc.org
[2] Wikipedia:http://zh.wikipedia.org/zh-cn/MVC