首頁(yè)技術(shù)文章正文

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

更新時(shí)間:2017-05-17 來(lái)源:web前端培訓(xùn)學(xué)院 瀏覽量:

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

一代目: 腳本式設(shè)計(jì)(無(wú)架構(gòu)設(shè)計(jì)):


下面這樣的代碼,就是無(wú)任何設(shè)計(jì)模式的產(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àn)檫@種編碼方式還是有他的優(yōu)點(diǎn)的。
短短的幾行代碼,包含了創(chuàng)建,樣式,綁定,插入。 balabala。。。。。
這種搞法雖有不少缺點(diǎn),但麻雀雖小五臟俱全,所有功能一應(yīng)俱全。早些年由于UI程序還處在一個(gè)懵懂期, 邏輯不算太復(fù)雜,代碼量也不會(huì)太多。這樣的搞法似乎也沒(méi)有什么問(wèn)題。 畢竟到達(dá)A B兩點(diǎn)最短的距離就是直線,上述代碼可以說(shuō)是實(shí)現(xiàn)某功能的最短路徑。 典型的例子就是 ASM (雖然匯編語(yǔ)言不是用來(lái)寫UI的),他們共有的缺點(diǎn)是 :入口單一 功能簡(jiǎn)單 不可維護(hù)
讓我們修改一下上面的邏輯:
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);
 
這里我們將一個(gè)功能拆分成了3個(gè)部分,即外觀 事件 和屬性。
函數(shù)將他們重新分離成一個(gè)個(gè)獨(dú)立的邏輯塊,這樣一定程度上達(dá)到了分離復(fù)用的目的,比如你想修改外觀,就去doCss函數(shù)里去找。。。
就像有錢人追求更多的財(cái)富,權(quán)貴追求更多權(quán)利一樣。
人類總在思考同一個(gè)問(wèn)題, 我們能不能做得更好。。
直到有一天。。。

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


對(duì)asp。net尤其是webForm,winForm模式熟悉的同學(xué),肯定對(duì)aspx 和 aspx。cs 這2種文件非常了解。
    
aspx是視圖文件,而對(duì)應(yīng)的。cs文件是他的相關(guān)邏輯處理文件 事件驅(qū)動(dòng)模式下,框架幫我們完成了基本的事件類型,我們要做的是在事件下完成相關(guān)業(yè)務(wù)邏輯。
在前端中,也可以找到二代目大人的影分身。。
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>
 
各文件各司其職,編寫的時(shí)候分離,在運(yùn)行的時(shí)候合并。這樣進(jìn)一步降低了功能之間的耦合度。 視圖看起來(lái)非常”清爽”,對(duì)應(yīng)的邏輯也被分離成一個(gè)個(gè)文件, 交由相應(yīng)的開(kāi)發(fā)人員處理。
如果你涉獵的技術(shù)范圍很廣,你會(huì)發(fā)現(xiàn)其實(shí)二代目大人已經(jīng)出現(xiàn)在諸多成熟的技術(shù)棧中。。。。
但是,沒(méi)過(guò)多久伊甸園歡樂(lè)的笑聲被下面這個(gè)需求打破。。。

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

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

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

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

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

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

本文版權(quán)歸黑馬程序員web前端開(kāi)發(fā)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處,謝謝!
作者:黑馬程序員web前端培訓(xùn)學(xué)院;
首發(fā):http://ko1818.cn/news/web.html

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!