教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

前端培訓之淺談框架模式(MVC MVP MVVM)(一)

更新時間:2016年12月06日11時50分 來源:傳智播客web前端培訓學院 瀏覽次數(shù):

前言:框架模式不是一門寫代碼的學問,而是一門管理與組織代碼的學問。其本質是一種軟件開發(fā)的模型。與設計模式不同,設計模式是在解決一類問題時總結抽象出的公共方法(工廠模式,適配器模式,單例模式,觀察者模式 。。。 。。。),他們與某種具體的技術棧無關。一種框架模式往往使用了多種設計模式,切不要把他們的關系搞混。
更多信息可以看看這本《Developing Backbone Application》

一代目: 腳本式設計(無架構設計):


下面這樣的代碼,就是無任何設計模式的產(chǎn)物:
JavaScript

1
2
3
4
5
6
7
8
9
const a = document.createElement("a");
a.innerHTML = "www.google.com";
a.href = "//www.google.com";
a.style.position = "absolute";
a.style.top = 100;
a.onclick = function(){
    console.log("google");
}
 document.body.appendChild(a);
 
嗯嗯~先別吐槽,因為這種編碼方式還是有他的優(yōu)點的。
短短的幾行代碼,包含了創(chuàng)建,樣式,綁定,插入。 balabala。。。。。
這種搞法雖有不少缺點,但麻雀雖小五臟俱全,所有功能一應俱全。早些年由于UI程序還處在一個懵懂期, 邏輯不算太復雜,代碼量也不會太多。這樣的搞法似乎也沒有什么問題。 畢竟到達A B兩點最短的距離就是直線,上述代碼可以說是實現(xiàn)某功能的最短路徑。 典型的例子就是 ASM (雖然匯編語言不是用來寫UI的),他們共有的缺點是 :入口單一 功能簡單 不可維護
讓我們修改一下上面的邏輯:
JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function doCss(a) {
    a.style.position = "absolute";
    a.style.top = 100;
}
function doEvent(a) {
    a.onclick = function(){
        alert("google");
    }
}
function doAttribute(a){
    a.innerHTML = "www.google.com";
    a.href = "//www.google.com";
}
const a = document.createElement("a");
doCss(a);
doEvent(a);
doAttribute(a)
document.body.appendChild(a);
 
這里我們將一個功能拆分成了3個部分,即外觀 事件 和屬性。
函數(shù)將他們重新分離成一個個獨立的邏輯塊,這樣一定程度上達到了分離復用的目的,比如你想修改外觀,就去doCss函數(shù)里去找。。。
就像有錢人追求更多的財富,權貴追求更多權利一樣。
人類總在思考同一個問題, 我們能不能做得更好。。
直到有一天。。。

二代目: 代碼文件分離(CodeBehind):


對asp。net尤其是webForm,winForm模式熟悉的同學,肯定對aspx 和 aspx。cs 這2種文件非常了解。
    
aspx是視圖文件,而對應的。cs文件是他的相關邏輯處理文件 事件驅動模式下,框架幫我們完成了基本的事件類型,我們要做的是在事件下完成相關業(yè)務邏輯。
在前端中,也可以找到二代目大人的影分身。。
JavaScript

1
2
3
4
5
6
7
8
<html>
<head>
    <link href="style.css" rel="stylesheet" />
</head>
<body>
    <script src="bundle.js" ></script>
</body>
</html>
 
各文件各司其職,編寫的時候分離,在運行的時候合并。這樣進一步降低了功能之間的耦合度。 視圖看起來非常”清爽”,對應的邏輯也被分離成一個個文件, 交由相應的開發(fā)人員處理。
如果你涉獵的技術范圍很廣,你會發(fā)現(xiàn)其實二代目大人已經(jīng)出現(xiàn)在諸多成熟的技術棧中。。。。
但是,沒過多久伊甸園歡樂的笑聲被下面這個需求打破。。。

為了實現(xiàn)他,在這里我只寫偽代碼了:

1
2
3
4
5
6
7
8
9
10
11
`購買蘋果按鈕`綁定事件如下:
1.int 蘋果數(shù)變量 + 1;
2.顯示蘋果數(shù)控件的值 = 蘋果數(shù)變量;
 
`購買梨按鈕`綁定事件如下:
1.int 梨數(shù)變量 + 1;
2.顯示梨數(shù)控件的值 = 梨數(shù)變量;
 
...`吃蘋果`
 
...`吃梨`
 
這里比較困難的是 第2步
就是如果顯示蘋果數(shù)的控件是另一個程序員開發(fā)的黑盒, 如何修改其值?
于是程序員A 去找 程序員B 尋求是否存在對應的 get/set 方法。
程序員B說, “有” 字還沒落地, 開發(fā)買梨的程序員C 又踹門進來了,問了同樣的問題, 后來才知道 開發(fā)吃蘋果功能的程序員D正在路上。。。
于是程序員B 不得不把接口的詳細信息寫到 wiki中, 于是 程序員CDEFGHIJKMLN 都看了wiki 懂了。
完成這件事 程序員B 寫wiki 花了 10分鐘, 程序員CDEFGHIJKMLN 看wiki每人花 1分鐘,一共團隊成本 20分鐘。
于是 wiki中這個 get/set 接口函數(shù)出現(xiàn)在了每一個被綁定的函數(shù)里。一共4個button 出現(xiàn)4次
ps: 這個get/set接口本質上就是一個view刷新接口
事情仍在在醞釀:
產(chǎn)品大爺發(fā)話了,要改成下面這樣:

多了一個求和。
于是偽代碼變成了這樣:

1
2
3
4
5
`購買蘋果按鈕`綁定事件如下:
1.int 蘋果數(shù)變量 + 1;
2.int 總和變量 = 蘋果數(shù)變量 + 梨數(shù)變量;
2.顯示蘋果數(shù)控件的值 = 蘋果數(shù)變量;
3.顯示總和控件的值 = 總和變量;

這次 程序員B為了人身安全,提前把 get/set 接口發(fā)布到了 wiki上。。
于是 總和控件的值 = 總和變量 這行代碼出現(xiàn)了 4次。
產(chǎn)品存在的意義,就是將程序狗虐到極致:
于是需求改成了這樣:

只是刪了一行。
于是 4個函數(shù)中所有相關代碼都被刪除。。。 共影響 4行代碼。。
段子講完了,其核心問題在于,按照事件進行的業(yè)務模塊劃分,有時候是不合理的,事件是用戶行為的入口,但不是程序邏輯的入口。 一個button的click就可能橫跨N個領域, 需要N個人來進行協(xié)作, 這部分邏輯到最后還是會耦合在一起,通過各種函數(shù)封裝進行解耦,無疑是揚湯止沸,而我們需要的是釜底抽薪
(第一節(jié)結束)

本文版權歸傳智播客web前端開發(fā)學院所有,歡迎轉載,轉載請注明作者出處,謝謝!
作者:傳智播客web前端培訓學院;
首發(fā):http://metathetuscanyresort.com/web/

0 分享到:
和我們在線交談!