當前位置:
首頁 > 知識 > 實例說明MVC,MVP,MVVM架構

實例說明MVC,MVP,MVVM架構

從一個簡單的例子去研究這三個架構。

注意,MVC,MVP,MVVM中的C,P,VM,下文都要controller指代。

需求如下

界面上顯示100,以及兩個按鈕,其中一個點一下加1,另外一個點一下減1

如圖

實例說明MVC,MVP,MVVM架構

誠然,這麼簡單的需求,並不需要用什麼架構去完成,可是如果是複雜的需求,要長篇大論才能說完,所以只拿簡單的來做例子,實際開發中,你在完成一個需求之前,是需要好好掂量是否要用架構,要的話,用什麼架構(不局限於這三個),架構裡面又要用什麼設計模式等等。經過我的實踐,發現,即使是架構改變了,view是可以完全不變的,所以先展現view層的代碼。

html部分


<span id="text">100</span>

<button id="upBtn">up</button>

<button id="downBtn">down</button>

js部分


function $(id) {

return document.querySelector(`#${id}`);

}

function View(controller) {

const upBtn = $("upBtn");

const downBtn = $("downBtn");

const textSpan = $("text");

this.render = function(model) {

textSpan.innerHTML = model.getValue();

}

upBtn.onclick = controller.up;

downBtn.onclick = controller.down;

}

render方法是核心,方法名稱不能改(後面要依賴這個render方法),其中要實現數據的展示邏輯,然後是一些點擊事件的綁定


MVC

model層


function Model() {

let value = 100;

this.up = function() {

value += 1;

};

this.down = function() {

value -= 1;

};

this.getValue = function() {

return value;

};

}

保存數據,並提供訪問,修改數據的方法,如果僅僅是這樣,那麼當model改變時,view是不知道的,所以需要讓model去通知view,我數據改變了,你要更新了。怎麼做呢?利用觀察者模式。在model中,增加一個數組views,去保存這個model對應的視圖,在修改數據的時候,遍歷views數組,調用每個view的render方法,參數是自己。

修改後的model


function Model() {

let value = 100;

const self = this;

const views = [];

this.up = function() {

value += 1;

};

this.down = function() {

value -= 1;

};

this.getValue = function() {

return value;

};

this.broadcast = function() {

views.forEach(view => view.render(self));

};

this.subscribe = function(cb) {

views.push(cb);

}

}

仔細看修改後的model,雖然增加了通知的方法(broadcast),但是在修改數據的方法(up和down)中並沒有去通知視圖。這個工作是由controller承擔的,另外把view註冊到model中,也是controller做的。

controller層


function Controller() {

let view = null;

let model = null;

this.up = function() {

// 修改數據

model.up();

// 通知視圖

model.broadcast();

};

this.down = function() {

model.down();

model.broadcast();

}

this.init = function() {

view = new View(this);

model = new Model();

// 把視圖註冊到model中

model.subscribe(view);

}

}

可以看到,controller把自己傳給了view去創建視圖,同時保存引用,創建model後,把view註冊到model中。同時實現了,改變數據,通知視圖的工作。

請一定要好好理解MVC,後面的MVP,MVVM都只是稍加修改而已。

MVP

在MVC中,改變數據,通知視圖,都是在controller做的,註冊視圖,以及通知視圖,這兩個方法的實現,都是model完成的,既然model負責數據處理,這兩個工作實際上和改變數據是沒關係的,把他們都轉移到controller中,不僅可以讓model層專註於數據處理,同時也方便多個視圖共用一個controller

model層


function Model() {

let value = 100;

this.up = function() {

value += 1;

};

this.down = function() {

value -= 1;

};

this.getValue = function() {

return value;

};

}

model層更小了,刪除了註冊,通知方法,只保存數據和提供獲取,修改數據的方法

controller層


function Controller() {

let views = [];

let model = null;

function broadcast() {

views.forEach(view => view.render(model));

}

this.up = function() {

model.up();

broadcast();

};

this.down = function() {

model.down();

broadcast();

}

this.init = function() {

views.push(new View(this));

model = new Model();

}

}

controller,增加了廣播方法,該方法的實現和調用都在controller中,另外,如果想多個視圖共用一個controller,如果這多個視圖都是同一個model,上面代碼能夠勝任,如果是這多個視圖是不同的model,那就要自己去實現好view和model的對應關係了(要用map來存儲對應關係,一個數組做不到)。


MVVM

可以看到,在MVP中,model也有一個up方法,controller也有一個up方法,只是增加了一個廣播方法的調用。是不是有些重複呢?把這兩個類似的方法整合到controller,model只負責保存數據,不實現修改數據的邏輯,這就是MVVM了,極大地精簡model

model層


function Model() {

let value = 100;

this.getValue = function() {

return value;

};

this.setValue = function(v) {

value = v;

}

}

其實,不用函數,單純地用一個變數,也是可以的,但是為了view層不變,view層中依賴model的getValue方法,所以這裡還是用函數去實現model

controller層


function Controller() {

let views = [];

let model = null;

function broadcast() {

views.forEach(view => view.render(model));

}

this.up = function() {

model.setValue(model.getValue() + 1);

broadcast();

};

this.down = function() {

model.setValue(model.getValue() - 1);

broadcast();

}

this.init = function() {

views.push(new View(this));

model = new Model();

}

}

精簡model的代價是controller要做更多的事情,實現修改數據的邏輯,通知視圖。如果用框架,react或者vue,通知視圖這部分框架會幫你實現,只要實現數據修改的邏輯就好了。

至此,三個架構都講完了,如果錯誤,歡迎討論。



更多優質內容推薦:

2017優就業就業促進計劃:http://www.ujiuye.com/zt/jycj/?wt.bd=zdy35845tt

中公教育「勤工儉學計劃」,給你一個真正0元學習IT的機會!

http://www.ujiuye.com/zt/qgjx/?wt.bd=zdy35845tt

IT職業教育:http://xue.ujiuye.com/

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT優就業 的精彩文章:

演算法的複雜度學習筆記
Eclipse連接SQL Server 2008資料庫以及問題總結
JPEG流封裝AVI視頻
設計模式學習筆記 之「多用組合,少用繼承」 C 代碼
大話數據結構——使用棧實現簡單的四則運算

TAG:IT優就業 |