一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

Web前端開發(fā)中的MCRV模式

  摘要

  針對前端開發(fā)中基于ajax的復(fù)雜頁面開發(fā)所面臨的代碼規(guī)模大,難以組織和維護,代碼復(fù)用性、擴展性和適應(yīng)性差等問題,本文嘗試以MVC思想為基礎(chǔ),結(jié)合Web前端開發(fā)中“內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為”相分離的開發(fā)標(biāo)準(zhǔn),提出一種將Web頁面代碼分為視圖(View,頁面靜態(tài)部分,包括內(nèi)容、結(jié)構(gòu)、表現(xiàn))、模型(Model,負(fù)責(zé)數(shù)據(jù)緩存、數(shù)據(jù)校驗與本地邏輯處理、發(fā)起ajax請求)、控制器(Controller,負(fù)責(zé)用戶和系統(tǒng)事件響應(yīng)、模型和渲染器調(diào)度)、渲染器(Renderer,對視圖的渲染,控制器與事件的綁定、數(shù)據(jù)搜集)的頁面開發(fā)新模式,并基于此模式提出了一個開發(fā)框架原型。

  關(guān)鍵字

  MCRV設(shè)計模式,Javascript,MVC,Web開發(fā)標(biāo)準(zhǔn)

  1. Web前端開發(fā)面臨的問題

  早期的Web頁開發(fā)(Web前端開發(fā))中,Web頁面較為簡單,大多數(shù)Web頁面的功能僅限于用HTML和簡單樣式展示靜態(tài)信息,或向服務(wù)器發(fā)送數(shù)據(jù),Web頁面與用戶的交互較少。隨著Web的發(fā)展,DHTML、CSS、Javascript等技術(shù)出現(xiàn),Web頁不再僅限于展示靜態(tài)信息,動態(tài)、交互成為Web頁的主流功能之一。與此同時,Web頁代碼規(guī)模也變的較大,頁面中的HTML、CSS、Javascript等代碼往往混雜在一起,如何很好的組織這些代碼,使Web客戶端程序具有很好的結(jié)構(gòu),易于閱讀和維護,成為Web前端開發(fā)人員面臨的一個難題。在實踐中,業(yè)界提出了“內(nèi)容(Content) - 結(jié)構(gòu)(Structure) - 表現(xiàn)(Presentation) - 行為(Behavior)”相分離的Web頁開發(fā)標(biāo)準(zhǔn)。在這種標(biāo)準(zhǔn)中,一個Web頁代碼可以分為如下四個部分:

  內(nèi)容:頁面實際要傳達的真正信息,包含數(shù)據(jù)、文檔或者圖片等。 結(jié)構(gòu):對內(nèi)容的劃分,使內(nèi)容更加具有邏輯性,易用性;類似頁面的標(biāo)題、作者、章、節(jié)、段落和列表。 表現(xiàn):用來描述內(nèi)容外觀,稱之為“表現(xiàn)”,主要指CSS樣式。 行為:行為就是對內(nèi)容的交互及操作效果;行為控制主要通過Javascript實現(xiàn)。

  內(nèi)容 - 結(jié)構(gòu) - 表現(xiàn) - 行為(CSPB)開發(fā)標(biāo)準(zhǔn)對Web頁包含的的代碼進行了分類,使代碼各個部分得到很好的分離,使Web頁初步具有了良好的結(jié)構(gòu)。

  隨后,Web進入了嶄新的Web2.0時代,以Gmail為代表的Web2.0應(yīng)用大量出現(xiàn),并且取得很大的成功。這類Web頁的典型特征是用一個基于ajax技術(shù)的無刷新的頁面完成大量復(fù)雜的功能。此類頁面包括Web IM、Web Map、Gmail等應(yīng)用,統(tǒng)稱為one-page Web應(yīng)用。同時,在企業(yè)級Web開發(fā)中,一個Web頁同時完成多個復(fù)雜功能的情況也越來越多。在這些復(fù)雜Web頁應(yīng)用中, Javascript代碼是此類富客戶端應(yīng)用程序的核心,負(fù)責(zé)與用戶的復(fù)雜交互和頁面展現(xiàn)。One-page Web頁面Javascript代碼規(guī)模往往非常龐大,邏輯復(fù)雜,動則千行以上,有時甚至需要一個團隊來完成一個頁面的開發(fā)。如何合理組織大量的Javascript代碼,使之具有良好的擴展性,能夠適應(yīng)需求的變化,使代碼易于維護,是廣大Web前端開發(fā)人員面臨的一大挑戰(zhàn)。

  縱觀Web應(yīng)用程序開發(fā)的歷史,Web后端開發(fā)(php、J2EE、ASP.NET)與Web客戶端開發(fā)的發(fā)展過程有一定的相似性,曾面臨類似的問題。最初,Web程序功能簡單,代碼較少時,所有的控制、邏輯、UI展現(xiàn)代碼混雜在一起;隨著Web發(fā)展,程序規(guī)模變大,按原有方式開發(fā)出的程序顯然不具有良好的結(jié)構(gòu),不利于大規(guī)模開發(fā)和后期維護,也不利于Web開發(fā)人員工作和角色的進一步細分,代碼復(fù)用性差,瓶頸開始出現(xiàn)。Web后端程序設(shè)計者的解決方法是進行代碼分類,將控制代碼與展現(xiàn)代碼開始分離, 于是Web后端開發(fā)從所謂的Model1發(fā)展到Model2;同時,傳統(tǒng)桌面程序設(shè)計中的MVC(模型-視圖-控制器)設(shè)計模式被引入,負(fù)責(zé)程序數(shù)據(jù)與邏輯計算的部分進一步分離出來,形成了Web后端開發(fā)中的MVC開發(fā)模式。MVC設(shè)計模式貫穿了軟件工程分而治之的思想,有效解決了Web后端程序設(shè)計中的代碼組織和復(fù)用問題。采用同一設(shè)計模式(MVC)也使代碼更容易被他人理解,保證代碼可靠性;它使Web開發(fā)工作可以細分為業(yè)務(wù)邏輯開發(fā)和UI展現(xiàn)開發(fā)。因此,MVC也利于團隊開發(fā)。那么,MVC設(shè)計思想是否也能應(yīng)用在前端開發(fā)中解決相關(guān)問題呢?既然問題具有許多相似性,筆者沿著相同的解決思路來試圖解決前端開發(fā)中的代碼組織問題。

  2. MVC設(shè)計模式

  在提出本文提出的MCRV設(shè)計模式之前,有必要對其所基于的MVC設(shè)計模式進行闡述。

  MVC這個概念很早之前就被人提起[1],它代表一種設(shè)計思想。MVC是Model-View-Conroller的縮寫,即模型 - 視圖 - 控制器。這種開發(fā)模式將一個應(yīng)用程序分為三個部分,模型(model)實現(xiàn)商業(yè)邏輯,提供數(shù)據(jù);視圖(view)負(fù)責(zé)向用戶呈現(xiàn)界面和接受用戶交互;控制器(controller)則負(fù)責(zé)響應(yīng)用戶交互請求,對用戶請求進行翻譯,根據(jù)不同的請求調(diào)用模型,執(zhí)行商業(yè)邏輯??刂破鞅举|(zhì)上是一個調(diào)度器 (dispatcher),通過其包含的各個方法(action)來執(zhí)行具體的商業(yè)邏輯。MVC各個部件以最小的耦合性協(xié)同工作,從而使程序具有良好的可擴展性和可維護性和復(fù)用性。

  MVC設(shè)計模式最開始被用于桌面程序設(shè)計,典型地用于相同的數(shù)據(jù)需要不同的用戶交互界面的設(shè)計場景。在經(jīng)典的MVC設(shè)計思想中,控制器負(fù)責(zé)響應(yīng)用戶事件,根據(jù)事件類型和參數(shù)調(diào)用模型或改變視圖。每個模型對應(yīng)一個或者多個視圖,當(dāng)模型被控制器調(diào)用而得到改變時,模型向所有向其注冊過的視圖發(fā)送通知,視圖根據(jù)從模型的中得到的信息改變外觀。這種設(shè)計模式可以用圖1表示。可以看出經(jīng)典MVC設(shè)計模式中Controller、Model 都可以改變視圖。

圖1 經(jīng)典MVC

  基于MVC模式的Web開發(fā)(后端)一般可以用圖2表示。在這種模式下,controller負(fù)責(zé)解析用戶瀏覽器請求的URL,根據(jù)URL自動調(diào)用controller中的不同的Action響應(yīng)用戶請求。Action調(diào)用model,然后將model返回的數(shù)據(jù)填充到view中,view被返回給用戶瀏覽器。Web服務(wù)端開發(fā)中典型的采用MVC模式的框架有Cakephp、Structs、Spring等等。

圖2 Server端Web開發(fā)中的MVC

  相對于早期的經(jīng)典MVC模式,Web開發(fā)中的MVC模式存在一些變化,因為對于一個桌面應(yīng)用程序而言,可以很方便地將視圖注冊給模型,當(dāng)模型數(shù)據(jù)發(fā)生改變時,即時通知視圖頁面發(fā)生改變;而對于Web應(yīng)用而言,即使將多個頁面注冊給一個模型,當(dāng)模型發(fā)生變化時,模型無法主動發(fā)送消息給Web頁面(因為Web應(yīng)用都是基于請求/響應(yīng)模式的),只有當(dāng)用戶請求瀏覽該頁面時,控制器才負(fù)責(zé)調(diào)用模型數(shù)據(jù)來更新Web頁面。同時,Web開發(fā)中的MVC也比經(jīng)典MVC具有更小的耦合性,因為Model不再與View發(fā)生交互,因此程序的結(jié)構(gòu)更加良好,使Web前端開發(fā)和業(yè)務(wù)邏輯開發(fā)相分離變的簡單。

  對于具有復(fù)雜交互邏輯和豐富界面的程序來說,MVC已被實踐證明是一種行之有效的設(shè)計和開發(fā)思想。采用MVC設(shè)計模式的系統(tǒng)具有較好的結(jié)構(gòu),較低的耦合性,代碼具有很好的維護性,能夠適應(yīng)復(fù)雜的業(yè)務(wù)邏輯和視圖展現(xiàn)變化。它也非常適合團隊開發(fā),使開發(fā)人員分為不同的角色,專注于自己負(fù)責(zé)部分的開發(fā)。

  3. MCRV設(shè)計模式

  綜上所述,MVC是解決具有復(fù)雜交互界面、代碼規(guī)模大的應(yīng)用程序面臨代碼組織、復(fù)用問題的有效設(shè)計模式。基于此,本文嘗試基于MVC設(shè)計思想解決前端開發(fā)中的類似問題。

  然而,在前端頁面開發(fā)中不能直接套用MVC設(shè)計模式。因為,前端開發(fā)中的Web頁面包含了HTML、CSS、Javascript等多個種類的代碼,相對Web后端來說,Web頁面整體就是一個負(fù)責(zé)UI展現(xiàn)、用戶本地交互、發(fā)送服務(wù)請求的大View,與經(jīng)典MVC及Web后端開發(fā)MVC模式中的View皆有不同。因此,需要具體問題具體分析。

  首先對Web頁面中的HTML、CSS、Javascript等代碼進一步分析,明確它們的具體功能分類。根據(jù)業(yè)界提出的Web開發(fā)標(biāo)準(zhǔn),Web頁首先被分為了"內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為"幾個部分。內(nèi)容、結(jié)構(gòu)、表現(xiàn)是頁面的靜態(tài)部分,主要負(fù)責(zé)UI的展現(xiàn),用戶操作指令(鍵盤、鼠標(biāo))的接受,因此,內(nèi)容、結(jié)構(gòu)、表現(xiàn)屬于視圖 (View)的范疇。行為主要就是Javascript代碼,負(fù)責(zé)對用戶操作指令的響應(yīng)。在復(fù)雜ajax應(yīng)用中, Javascript代碼的功能一般包括:響應(yīng)用戶指令,執(zhí)行數(shù)據(jù)驗證/處理、執(zhí)行客戶端交互邏輯,向服務(wù)器發(fā)送ajax請求,接受并處理服務(wù)器返回的數(shù)據(jù),根據(jù)數(shù)據(jù)改變UI(向頁面結(jié)構(gòu)填充內(nèi)容數(shù)據(jù)、變換樣式等)?;谀P?視圖-控制器分離的思想,Javascript代碼中的數(shù)據(jù)驗證/處理、本地業(yè)務(wù)邏輯計算、向服務(wù)器發(fā)請求獲取數(shù)據(jù)的功能,對應(yīng)模型(Model)的功能;響應(yīng)(翻譯)用戶操作指令,根據(jù)指令執(zhí)行業(yè)務(wù)邏輯處理的功能,屬于控制器(Controller)的功能;而接受處理過的數(shù)據(jù),根據(jù)數(shù)據(jù)修改頁面的內(nèi)容/結(jié)構(gòu)/樣式的功能既不屬于控制器的功范疇,也不屬于模型的功能范疇,這部分代碼因為根據(jù)數(shù)據(jù)對View進行呈現(xiàn)(render),可以命名為Renderer(渲染器或呈現(xiàn)器)。

  根據(jù)前述分析,本文提出了MCRV設(shè)計模式,如圖3所示。闡述如下:

圖3: MCRV開發(fā)模式

  M(Model):模型,完成數(shù)據(jù)驗證、數(shù)據(jù)處理,執(zhí)行客戶端業(yè)務(wù)邏輯計算,或向服務(wù)器發(fā)起ajax請求調(diào)用服務(wù)端邏輯、接受返回的數(shù)據(jù),將處理后的數(shù)據(jù)返回控制器。 C(Controller):控制器,控制器響應(yīng)View上的事件,根據(jù)事件調(diào)度執(zhí)行模型的業(yè)務(wù)邏輯,從業(yè)務(wù)邏輯獲取返回數(shù)據(jù),調(diào)度相應(yīng)的渲染器(Render)來完成界面展現(xiàn)。在這個過程中控制器會有數(shù)據(jù)的傳遞:控制器調(diào)用模型中的邏輯時會傳送Renderer搜集的數(shù)據(jù)(form表單各域的name/value、其他控制參數(shù)),模型執(zhí)行邏輯后返回作為執(zhí)行結(jié)果的數(shù)據(jù)給控制器,控制器根據(jù)數(shù)據(jù)來調(diào)用渲染器(renderer)來完成界面呈現(xiàn)(rendering),呈現(xiàn)(rendering)就是修改頁面結(jié)構(gòu)、內(nèi)容和樣式的過程。數(shù)據(jù)傳遞過程可以用圖4表示。 R(Renderer):渲染器(呈現(xiàn)器),渲染器被控制器調(diào)用,接受從控制器傳遞的數(shù)據(jù),完成對界面的具體渲染。渲染器也負(fù)責(zé)控件(widget)的初始化,及建立Controller與具體事件的對應(yīng)關(guān)系,事件發(fā)生時負(fù)責(zé)搜集View上的數(shù)據(jù)傳送到Controller。 V(View):視圖,視圖是用戶最終看到的整個Web界面,由結(jié)構(gòu)、內(nèi)容、樣式(表現(xiàn))等靜態(tài)內(nèi)容共同構(gòu)成;View由Renderer進行初始化渲染和修改。

 

圖4:數(shù)據(jù)傳遞過程

  可以看到在MCRV開發(fā)模式中,Controller處于控制中心的位置,Model完成具體的商業(yè)邏輯計算以及向后端發(fā)起ajax請求返回數(shù)據(jù)的功能。Controller與Model、Renderer之間的交互本質(zhì)上是數(shù)據(jù)交互的過程,它們之間存在著一個數(shù)據(jù)流,如圖4所示。因此,制定Controller、Model、Renderer之間的交互接口時,數(shù)據(jù)格式定義很重要。

  4. 基于MCRV設(shè)計模式的Demo

  下面是一個用MCRV模式來開發(fā)的Demo頁面,頁面的功能是用表格展示和修改用戶信息。Javascript使用了jQuery庫。頁面界面如圖5所示。頁面代碼在程序清單1中

圖5:基于MCRV設(shè)計模式的用戶管理Demo

  程序清單1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=7"/>
<title>MCRV 設(shè)計模式 Demo</title>
<style type="text/css">
/********表現(xiàn)*********/
table
{width:100%;border-collapse: collapse;}
td
{border: 1px solid black;padding: 2px;}
#container
{width:800px;margin:0px auto;}
#tbUsers
{margin:20px auto;}
#tbUsers th
{background-color: navy;color:white;text-align: center;vertical-align: middle;border:1px solid navy}
#tbUsers td
{text-align: center;}
.editCaption
{width:100px;text-align: right;}
.buttonMargin
{margin:0px 20px;}
.buttonContainer
{text-align: center;vertical-align: middle;height:50px}
</style>
<script src="./jquery-1.3.2.min.js" type="text/Javascript" charset="utf-8"></script>
</head>
<body>
<!-------結(jié)構(gòu)--------->
<div id="container">
<table id="tbUsers">
<thead><th>id</th><th>姓名</th><th>年齡</th><th>修改</th></thead>
<tbody/>
</table>
<div style="display: none;" id="dvEditPanel">
<form id="frmModify" name="frmModify">
<table>
<tr>
<td class="editCaption"> id: </td>
<td><span id="spID"></span></td>
</tr>
<tr>
<td class="editCaption"> 姓名: </td>
<td><input type="text" size="20" id="txtName"/></td>
</tr>
<tr>
<td class="editCaption"> 年齡: </td>
<td><input type="text" size="20" id="txtAge"/></td>
</tr>
<tr>
<td colspan="2" class="buttonContainer">
<button id="btnSubmitModify" class="buttonMargin" type="button">提交</button>
<button id="btnCancelModify" class="buttonMargin" type="button">取消</button>
</td>
</tr>
</table>
</form>

</div>
</div>
<script>
/***************************行為********************************/
var UserManagerMCR;
$(
function()
{
UserManagerMCR
=new MCR(UserController,UserModel,UserRenderer);
});

/*
* MCR 三元組
*/
function MCR(Controller,Model,Renderer)
{
this.controller=new Controller();
this.model=new Model();
this.renderer=new Renderer();
this.controller.model=this.model;
this.controller.renderer=this.renderer;
this.model.controller=this.controller;
this.renderer.controller=this.controller;
if(typeofthis.model.init=="function")
{
this.model.init();
}
if(typeofthis.renderer.init=="function")
{
this.renderer.init();
}
if(typeofthis.controller.init=="function")
{
this.controller.init();
}
}

/*
* 控制器
*/
function UserController()
{
this.init=function()
{
this.initUserList();
}

this.initUserList=function()
{
var list=this.model.getUserList();
this.renderer.renderUserList(list);
}

this.beginModify=function(data)
{
var user=this.model.getUserByID(data.id);
this.renderer.showModifyUI(user);
}

//提交修改
this.submitModify=function(user)
{
var result=this.model.modifyUser(user);
if(result.success)
{
var list=this.model.getUserList();
this.renderer.renderUIWhenSubmitModifySuccess(list);
}
else
{
alert(result.msg);
}
}

//取消修改
this.cancelModify=function()
{
this.renderer.hideModifyUI();
}

}

/*
* 模型
*/
function UserModel()
{
//模擬的數(shù)據(jù),實際應(yīng)用中經(jīng)常從服務(wù)器獲取

this.init=function()
{
this.data = [
{id:
0,name:"John",age:22},
{id:
1,name:"Tom",age:30},
{id:
2,name:"Tony",age:25}
];
}

//獲得用戶數(shù)據(jù)列表
this.getUserList=function()
{
//todo ,可能ajax從后端返回
returnthis.data;
}

//獲得用戶數(shù)據(jù)
this.getUserByID=function(id)
{
var ix;
$.each(
this.data,function(i,item){if(item["id"]==id ) { ix=i; returnfalse;}});
returnthis.data[ix];
}

//修改用戶數(shù)據(jù)
this.modifyUser=function(user)
{
var result={success:true,msg:"修改成功"};
//todo,驗證參數(shù)user
//todo,修改用戶數(shù)據(jù)
$.each(this.data,function(i,item)
{
if(item["id"]==user["id"])
{
item[
"name"]=user["name"];
item[
"age"]=user["age"]
returnfalse;
}
});
return result;
}
}
/*
* 渲染器
*/
function UserRenderer()
{
this.init=function()
{
var me=this;
$(
"#btnSubmitModify").click(function()
{
var user={id:$("#spID").text(),name:$("#txtName").val(),age:$("#txtAge").val()};
me.controller.submitModify(user);
});
$(
"#btnCancelModify").click(function()
{
me.controller.cancelModify();
});
$(
"#tbUsers .modify").live("click",function()
{
var id=$(this).attr("uid");
me.controller.beginModify({
"id":id});
});
}

this.renderUserList=function(list)
{
var htm=[];
for(var ix=0;ix<list.length;ix++)
{
htm.push(
"<tr><td>"+list[ix]["id"]+"</td>"+"<td>"+list[ix]["name"]+"<td>"+list[ix]["age"]+"</td>"
+"<td>"+"<a class='modify' href='Javascript:void(0)' uid='"+list[ix]["id"]+"'>修改</a></td>"+"</tr>");
}
$(
"#tbUsers").children("tbody").html(htm.join(""));
}

this.showModifyUI=function(user)
{
$(
"#dvEditPanel").show();
$(
"#spID").text(user["id"]);
$(
"#txtName").val(user["name"]);
$(
"#txtAge").val(user["age"]);
}

this.hideModifyUI=function()
{
document.frmModify.reset();
$(
"#dvEditPanel").hide();
}

this.renderUIWhenSubmitModifySuccess=function(list)
{
this.hideModifyUI();
this.renderUserList(list);
}
}
</script>
</body>
</html>

it知識庫Web前端開發(fā)中的MCRV模式,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 色哟哟视频在线 | 欧美特黄特刺激a一级淫片 欧美特黄特色aaa大片免费看 | 国产乱了 | 好吊妞免费视频 | 韩国毛片免费 | 福利影院在线看 | 在线国产一区二区 | 黄色在线观看网站 | 综合天天色 | 亚洲小说图片视频 | 久久99精品久久久久久青青91 | 亚洲国产99在线精品一区二区 | 精品国产午夜久久久久九九 | 久久ww | 在线观看一区二区三区视频 | 国产精品福利在线观看秒播 | 国内免费高清视频在线观看 | 在线观看视频黄色 | 国产成人精品久久一区二区三区 | 美女久久精品 | 男人猛桶女人下面视频国产 | 国产中文字幕在线免费观看 | 91免费国产视频 | 经典毛片 | 天天躁天天碰天天看 | 国产区视频在线 | 色综合久久加勒比高清88 | 久久伊人中文字幕有码 | 久草手机在线播放 | 97精品国产91久久久久久久 | 亚洲深夜视频 | 草草免费 | 天天擦天天干 | a级国产乱理论片在线观看看 | 欧美视频久久久 | 一区二区三区不卡视频 | 国产精品大白天新婚身材 | 激情五月婷婷在线 | 狠狠做五月深爱婷婷天天综合 | 一级寡妇乱色毛片全场免费 | 国产成人小视频在线观看 |