MVC模式及Extjs框架應用

MVC起源

幾乎全部應用系統都是由這三部分組成:表示企業數據和業務規則的數據,用來展現數據的,用戶看到並與之交互的界面,負責轉發請求,對請求的處理;協調數據和展現的邏輯。在MVC出現以前,這三部分都是寫在一塊兒的,是耦合的,這對軟件工程是很差的。設計模式

1979年,Trygve Reenskaug在Smalltalk-80系統上首次提出了MVC的概念,最初的時候叫作Model-View-Controller-Editor。1994年,Gof(Gang of Four)在 Design Patterns: Elements of Reusable Object-Oriented Software 一書中對MVC模式作了深刻的解析。架構

Trygve Reenskaug最初提出MVC的目的是爲了把數據(Model)和視圖(View)分離開來,而後用控制器(Controller)做膠水來粘合M和V之間的關係。很顯然,這樣作的目的是爲了實現注意點分離這樣一個更高層次的設計理念,View就只負責視圖相關的東西,Model就只負責描述數據模型,Controller負責總控,各自協做。app

傳統MVC

MVC模式

經過把職責、性質相近的成分歸結在一塊兒,不相近的進行隔離,MVC將系統分解爲模型、視圖、控制器三部分,每一部分都相對獨立,職責單一,在實現過程當中能夠專一於自身的核心邏輯。MVC是對系統複雜性的一種合理的梳理與切分。框架

MVC

Model對view和controller均可知,view對controller可知,controller對誰都不可知。ide

這裏爲了容易理解,我想用咱們實驗室三個屋來打個比方,小屋是view,中屋是controller,大屋是model。函數

  1. 用戶請求、試圖選擇:小屋不認識中屋,可是中屋認識小屋,小屋一旦有需求,中屋就會默默地知足他的要求,好比:小屋的賈老師大喊一聲「把三木球拉出去」,中屋就來了一我的把三木球拉了出去。this

  2. 狀態查詢:小屋認識大屋,小屋想知道大屋的郭師兄今天穿了件什麼顏色的衣服,就跑去看了看,哦,原來郭師兄穿了件綠色的衣服。編碼

  3. 用戶請求、狀態改變、通知改變:賈老師大喊一聲「給郭師兄換件紅色的衣服」,隔壁屋的一我的就去給他換了,郭師兄換完衣服,開心地大喊了一句「我換了件紅色的衣服!」。spa

其實這裏,我對狀態的理解仍是有些模糊,暫且把它當作數據,好比登陸,某種角色的用戶登陸後,controller會告訴model改變狀態,而後通知給view,也就是展現給該角色的用戶相應的數據。設計

MVC實現

GoF (Gang of Four,四人組, 《Design Patterns: Elements of Reusable Object-Oriented Software》/《設計模式》一書的做者:Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides)並無把MVC說起爲一種設計模式,而是把它當作"一組用於構建用戶界面的類集合"。在他們看來,它實際上是其它兩個個經典的設計模式的演變:觀察者模式(Observer)(Pub/Sub)和策略模式(Strategy)。

正如咱們所討論的,models表示應用的數據,而views處理屏幕上展示給用戶的內容。爲此,MVC在覈心通信上基於推送/訂閱模型。

model與view的推送/訂閱

view:
models[0...n];
callbackModelEvents[0...n];

for(model 0...n)
    for(model[i].Event(0...n))
        this.on(Events[j], callbackModelEvent[k]);

View(訂閱者)註冊了一組model和model對應的事件的處理函數,當model(發佈者)一旦發佈了消息,view就會接收。

view與controller的推送/訂閱

View和controller同上。

Extjs下的MVC

Extjs框架

Extjs這個框架是典型的MVC模式,它幫咱們完成了MVC的大部分工做,爲了體現MVC模式,提供給咱們這樣的接口,固然,咱們用戶的主要代碼就是寫在這裏的。

Extjs工程目錄

這是ExtJs4.2的工程文件目錄,咱們的代碼就寫在controller、model、store、view這四個文件夾下,接下來,咱們看一下Ext代碼是怎麼寫的。

Ext.define("Srims.view.patent.PatentList", {
    extend: 'Ext.grid.Panel',
    store: [patent.patents],
    ……
});

在view中,咱們能夠配置當前view對應的store(即數據),當數據更新時,從model發出消息,展現在view中,固然,咱們須要配置這麼一行代碼,剩下的框架已經幫咱們作好了。

Ext. define('Srims.controller.patent.patentList', {
    extend: 'Ext.app.Controller',
    views: ['patent.patentList'],
    model:[patent.patents],
    ……
    'patentlist button[itemId=btnDeletePatent]': { //刪除按鈕點擊響應
            click: function (button, e) {
                Ext.MessageBox.confirm('確認', '確認刪除選中記錄麼?',
                    function (btn) {
                        if (btn == 'yes') {
                            var panel = button.up('panel');
                              var selectionRecord = panel.getSelectionModel().getSelection()[0];

                              var store = panel.getStore();
                            store.remove(selectionRecord);

                        }
                    }, this);
                    ……
            }
        },
            ……
});

在controller中,能夠配置當前controller對應的view、model,在方法中也能夠對view對應的store操做,也能夠直接建立store(model)的實例,對其操做。

經過這樣配置,能夠實現觀察者模式。

問題一:view複用的問題

view與controller的多對多關係

在Ext中,view和controller是多對多的關係,好比,controller對它註冊的多個view進行消息響應或者操做,假如要選擇view1通常經過get方法,就是get加view1做爲方法名,使用的,這樣看上去是沒問題的。

view與controller的類和實例的相互關係

可是Ext是基於類的,實際應用中,咱們一般是這樣的,因爲不少view長得很像甚至相同,咱們習慣複用同一個view類,這樣,一個view類對應着多個實例。咱們在controller中的全部方法都是針對他對應的view類的,當咱們建立了一個controller實例,經過該類中的方法找到對應的view類,來操做這個view類對應的view實例,這時候,一個view對應着多個實例,操做就會產生混亂。

固然,只要咱們在編碼是注意經過controller中適當處理邏輯,在view中適當添加標誌位,混亂和衝突也是能夠解決的。因此從此,適當複用而且提升編碼能力,也是沒問題的。

問題二:粒度問題

在傳統的MVC架構裏包括Extjs,一個controller可能有多個方法,每一個方法每每對應一個user action,所以,一個controller每每對應多個user action。傳統MVC架構裏將一個user action委派到某個controller的某個方法的過程。

目前,不少平臺的主流MVC框架在設計上都引入了command模式,command模式的引入改變了傳統MVC框架的結構,受衝擊最大的就是 controller。

在基於command的MVC架構裏,一個command每每只對應一個user action,在該架構裏變成了將useraction與command一一綁定的過程。

controller向command的轉變

主流MVC框架向command轉型一個很是重要的緣由就是:因爲缺乏合理的組織依據,controller的粒度很難拿捏。

controller不一樣於view與model,view與model都有各自自然的粒度組織依據,view的組織粒度直接承襲用戶界面設計,model的組織粒度則是依據某種分析設計思想(如OOA/D)進行領域建模的結果,controller須要同時協調view與model,可是view與model的組織結構和粒度都是不對等的,這就使得controller面臨一個"在多大視圖範圍內溝通與協調多少領域對象"的問題,因爲找不出合理的組織依據,設計者在設計controller時每每感到無所適從。

Extjs雖然在這方面考慮欠佳,但咱們能作的就是遵循良好的設計原則,對某些較"大"的user action方法進行分解,從中抽離出一些可複用的部分封裝成一些較"小"的方法,儘可能減少代碼的冗餘。

相關文章
相關標籤/搜索