在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ MVC
中介者模式
MVVM
亨元模式
設(shè)計(jì)模式分類概覽表
ES Harmony
組合模式
CommonJS
jQuery 插件的設(shè)計(jì)模式
外觀模式
觀察者模式
建造者模式
構(gòu)造器模式
外觀模式
簡介
AMD
原型模式
設(shè)計(jì)模式的分類
觀察者模式
命名空間模式
代理模式
編寫設(shè)計(jì)模式
適配器模式
反模式
什么是設(shè)計(jì)模式
模塊化模式
MVC
Mixin 模式
裝飾模式
設(shè)計(jì)模式的結(jié)構(gòu)
單例模式
迭代器模式
命令模式
工廠模式
MVP
暴露模塊模式
惰性初始模式

MVC

MVC是一個(gè)架構(gòu)設(shè)計(jì)模式,它通過分離關(guān)注點(diǎn)的方式來支持改進(jìn)應(yīng)用組織方式。它促成了業(yè)務(wù)數(shù)據(jù)(Models)從用戶界面(Views)中分離出來,還有第三個(gè)組成部分(Controllers)負(fù)責(zé)管理傳統(tǒng)意義上的業(yè)務(wù)邏輯和用戶輸入。該模式最初是由Trygve Reenskaug在研發(fā)Smalltalk-80 (1979)期間設(shè)計(jì)的,當(dāng)時(shí)它起初被稱作Model-View-Controller-Editor。在1995年的“設(shè)計(jì)模式: 面向?qū)ο筌浖械目蓮?fù)用元素” (著名的"GoF"的書)中,MVC被進(jìn)一步深入的描述,該書對MVC的流行使用起到了關(guān)鍵作用。

Smalltalk-80 MVC

了解一下最初的MVC模式打算解決什么問題是很重要的,因?yàn)樽詮恼Q生之日起它已經(jīng)發(fā)生了很大的改變?;氐?0年代,圖形用戶界面還很稀少,一個(gè)被稱為分離展示的概念開始被用來清晰的劃分下面兩種對象:領(lǐng)域?qū)ο?,它對現(xiàn)實(shí)世界里的概念進(jìn)行建模(比如一張照片,一個(gè)人), 還有展示對象,它被渲染到用戶屏幕上進(jìn)行展示。

Smalltalk-80作為MVC的實(shí)現(xiàn),把這一概念進(jìn)一步發(fā)展,產(chǎn)生這樣一個(gè)觀點(diǎn),即把應(yīng)用邏輯從用戶界面中分離開來。這種想法使得應(yīng)用的各個(gè)部分之間得以解耦,也允許該應(yīng)用中的其它界面對模型進(jìn)行復(fù)用。關(guān)于Smalltalk-80的MVC架構(gòu),有幾點(diǎn)很有趣,值得注意一下:

  • 模型表現(xiàn)了領(lǐng)域特定的數(shù)據(jù),并且不用考慮用戶界面(視圖和控制器).當(dāng)一個(gè)模型有所改變的時(shí)候,它會通知它的觀察者。
  • 視圖表現(xiàn)了一個(gè)模型的當(dāng)前狀態(tài).觀察者模式被用來讓視圖在任何時(shí)候都知曉模型已經(jīng)被更新了或者被改變了。
  • 展現(xiàn)受到視圖的照管,但是不僅僅只有一個(gè)單獨(dú)的視圖或者控制器——每一個(gè)在屏幕上展現(xiàn)的部分或者元素都需要一個(gè)視圖-控制器對。
  • 控制器在這個(gè)視圖-控制器對中扮演著處理用戶交互的角色(比如按鍵或者點(diǎn)擊動作),做出對視圖的選擇。

開發(fā)者有時(shí)候會驚奇于他們了解到的觀察者模式(如今已經(jīng)被普遍的作為發(fā)布/訂閱的變異實(shí)現(xiàn)了)已經(jīng)在幾十年以前被作為MVC架構(gòu)的一部分包含進(jìn)去了.在Smalltalk-80的 MVC中,視圖觀察著模型.如上面要點(diǎn)中所提到的,模型在任何時(shí)候發(fā)生了改變,視圖就會做出響應(yīng).一個(gè)簡單的示例就是一個(gè)由股票市場數(shù)據(jù)支撐的應(yīng)用程序——為了應(yīng)用程序的實(shí)用性,任何對于我們模型中數(shù)據(jù)的改變都應(yīng)該導(dǎo)致視圖中的結(jié)果實(shí)時(shí)的刷新。

Martin Fowler在過去數(shù)年完成了對原生MVC有關(guān)問題進(jìn)行寫作的優(yōu)秀工作,如果對關(guān)于Smalltalk-80的MVC的更深入的歷史信息感興趣的話,我建議您讀一讀他的作品。

JavaScript 開發(fā)者可以使用的 MVC

我們已經(jīng)回顧了70年代,讓我們回到當(dāng)下回到眼前?,F(xiàn)在,MVC模式已經(jīng)被應(yīng)用到大范圍的編程語言當(dāng)中,包括與我們關(guān)系最近的JavaScript。JavaScript領(lǐng)域現(xiàn)在有一些鼓勵(lì)支持MVC (或者是它的變種,我們稱之為MV* 家族)的框架,允許開發(fā)者不用付出太多的努力就可以往他們的應(yīng)用中添加新的結(jié)構(gòu)。

這些框架包括諸如Backbone, Ember.js和AngularJS??紤]到避免出現(xiàn)“意大利面條”式的代碼的重要性,該詞是指那些由于缺乏結(jié)構(gòu)設(shè)計(jì)而導(dǎo)致難于閱讀和維護(hù)的代碼,對現(xiàn)代JavaScript開發(fā)者來說,了解該模式能夠提供什么已經(jīng)是勢在必行。這使得我們可以有效的領(lǐng)會到,這些框架能讓我們以不同的方式做哪些事情。

我們知道MVC由三個(gè)核心部分組成:

Models

Models管理一個(gè)業(yè)務(wù)應(yīng)用的數(shù)據(jù)。它們既與用戶界面無關(guān)也與表現(xiàn)層無關(guān),相反的它們代表了一個(gè)業(yè)務(wù)應(yīng)用所需要的形式唯一的數(shù)據(jù)。當(dāng)一個(gè)model改變時(shí)(比如當(dāng)它被更新時(shí)),它通常會通知它的觀察者(比如我們很快會介紹的views)一個(gè)改變已經(jīng)發(fā)生了,以便觀察者采取相應(yīng)的反應(yīng)。

為了更深的理解models,讓我們假設(shè)我們有一個(gè)JavaScript的相冊應(yīng)用。在一個(gè)相冊中,照片這個(gè)概念配得上擁有一個(gè)自己的model, 因?yàn)樗砹颂囟I(lǐng)域數(shù)據(jù)的一個(gè)獨(dú)特類型。這樣一個(gè)model可以包含一些相關(guān)的屬性,比如標(biāo)題,圖片來源和額外的元數(shù)據(jù)。一張?zhí)囟ǖ恼掌梢源鎯Φ絤odel的一個(gè)實(shí)例中,而且一個(gè)model也可以被復(fù)用。下面我們可以看到一個(gè)用Backbone實(shí)現(xiàn)的被簡化的model例子。

var Photo = Backbone.Model.extend({

    // 照片的默認(rèn)屬性
    defaults: {
      src: "placeholder.jpg",
      caption: "A default image",
      viewed: false
    },

    // 確保每一個(gè)被創(chuàng)建的照片都有一個(gè)`src`.
    initialize: function() {
       this.set( { "src": this.defaults.src} );
    }

});

不同的框架其內(nèi)置的模型的能力有所不同,然而他們對于屬性驗(yàn)證的支持還是相當(dāng)普遍的,屬性展現(xiàn)了模型的特征,比如一個(gè)模型標(biāo)識符.當(dāng)在一個(gè)真實(shí)的世界使用模型的時(shí)候,我們一般也希望模型能夠持久.持久化允許我們用最近的狀態(tài)對模型進(jìn)行編輯和更新,這一狀態(tài)會存儲在內(nèi)存、用戶的本地?cái)?shù)據(jù)存儲區(qū)或者一個(gè)同步的數(shù)據(jù)庫中。

另外,模型可能也會被多個(gè)視圖觀察著。如果說,我們的照片模型包含了一些元數(shù)據(jù),比如它的位置(經(jīng)緯度),照片中所展現(xiàn)的好友(一個(gè)標(biāo)識符的列表)和一個(gè)標(biāo)簽的列表,開發(fā)者也許會選擇為這三個(gè)方面的每一個(gè)提供一個(gè)單獨(dú)的視圖。

為現(xiàn)代MVC/MV*框架提供一種將模型組合到一起的方法(例如,在Backbone中,這些分組作為“集合”被引用)并不常見。管理分組中的模型允許我們基于來自分組中所包含的模型發(fā)生改變的通知,來編寫應(yīng)用程序邏輯.這避免了手動設(shè)置去觀察每一個(gè)單獨(dú)的模型實(shí)體的必要。

如下是一個(gè)將模型分組成一個(gè)簡化的Backbone集合的示例:

var PhotoGallery = Backbone.Collection.extend({

    // Reference to this collection's model.
    model: Photo,

    // Filter down the list of all photos
    // that have been viewed
    viewed: function() {
        return this.filter(function( photo ){
           return photo.get( "viewed" );
        });
    },

    // Filter down the list to only photos that
    // have not yet been viewed
    unviewed: function() {
      return this.without.apply( this, this.viewed() );
    }
});

MVC上舊的文本可能也包含了模型管理著應(yīng)用程序狀態(tài)的一種概念的引述.Javascript中的應(yīng)用程序狀態(tài)有一種不同的意義,通常指的是當(dāng)前的"狀態(tài)",即在一個(gè)固定點(diǎn)上的用戶屏幕上的視圖或者子視圖(帶有特定的數(shù)據(jù)).狀態(tài)是一個(gè)經(jīng)常被談?wù)摰降脑掝},看一看單頁面應(yīng)用程序,其中的狀態(tài)的概念需要被模擬。

總而言之,模型主要關(guān)注的是業(yè)務(wù)數(shù)據(jù)。

視圖

視圖是模型的可視化表示,提供了一個(gè)當(dāng)前狀態(tài)的經(jīng)過過濾的視圖。Smaltalk的視圖是關(guān)于繪制和操作位圖的,而JavaScript的視圖是關(guān)于構(gòu)建和操作DOM元素的。

一個(gè)視圖通常是模型的觀察者,當(dāng)模型改變的時(shí)候,視圖得到通知,因此使得視圖可以更新自身。用設(shè)計(jì)模式的語言可以稱視圖為“啞巴”,因?yàn)樵趹?yīng)用程序中是它們關(guān)于模型和控制器的了解是受到限制的。

用戶可以和視圖進(jìn)行交互,包括讀和編輯模型的能力(例如,獲取或者設(shè)置模型的屬性值)。因?yàn)橐晥D是表示層,我們通常以用戶友好的方式提供編輯和更新的能力。例如,在之前我們討論的照片庫應(yīng)用中,模型編輯可以通過“編輯”視圖來進(jìn)行,這個(gè)視圖里面,用戶可以選擇一個(gè)特定的圖片,接著編輯它的元數(shù)據(jù)。

而實(shí)際更新模型的任務(wù)落到了控制器上面(我們很快就會講這個(gè)東西)。

讓我們使用vanilla JavaScript 實(shí)現(xiàn)的例子來更深入的探索一下視圖。下面我們可以看到一個(gè)函數(shù)創(chuàng)建了一個(gè)照片視圖,使用了模型實(shí)例和控制器實(shí)例。

我們在視圖里定義了一個(gè)render()工具,使用一個(gè)JavaScript模板引擎來用于渲染照片模型的內(nèi)容(Underscore的模板),并且更新了我們視圖的內(nèi)容,供照片EI來參考。

照片模型接著將我們的render()函數(shù)作為一個(gè)其一個(gè)訂閱者的回調(diào)函數(shù),這樣通過觀察者模式,當(dāng)模型發(fā)生改變的時(shí)候,我們就能觸發(fā)視圖的更新。

人們可能會問用戶交互如何在這里起作用的。當(dāng)用戶點(diǎn)擊視圖中的任何元素,不是由視圖決定接下來怎么做。而是由控制器為視圖做決定。在我們的例子中,通過為photoEI增加一個(gè)事件監(jiān)聽器,來達(dá)到這個(gè)目的,photoEI將會代理處理送往控制器的點(diǎn)擊行為,在需要的時(shí)候?qū)⒛P托畔⒑褪录徊鬟f。

這個(gè)架構(gòu)的好處是每個(gè)組件在應(yīng)用工作的時(shí)候都扮演著必要的獨(dú)立的角色。

var buildPhotoView = function ( photoModel, photoController ) {

  var base = document.createElement( "div" ),
      photoEl = document.createElement( "div" );

  base.appendChild(photoEl);

  var render = function () {
          // We use a templating library such as Underscore
          // templating which generates the HTML for our
          // photo entry
          photoEl.innerHTML = _.template( "#photoTemplate" , {
              src: photoModel.getSrc()
          });
      };

  photoModel.addSubscriber( render );

  photoEl.addEventListener( "click", function () {
    photoController.handleEvent( "click", photoModel );
  });

  var show = function () {
    photoEl.style.display = "";
  };

  var hide = function () {
    photoEl.style.display = "none";
  };

  return {
    showView: show,
    hideView: hide
  };

};

模板

在支持MVC/MV*的JavaScript框架的下,有必要簡略的討論一下JavaScript的模板以及它們與視圖之間的關(guān)系,在上一小節(jié),我們已經(jīng)接觸到這種關(guān)系了。

歷史已經(jīng)證明在內(nèi)存中通過字符串拼接來構(gòu)建大塊的HTML標(biāo)記是一種糟糕的性能實(shí)踐。開發(fā)者這樣做,就會深受其害。遍歷數(shù)據(jù),將其封裝成嵌套的div,使用例如document.writeto 這樣過時(shí)的技術(shù)將"模板"注入到DOM中。這樣通常意味著校本化的標(biāo)記將會嵌套在我們標(biāo)準(zhǔn)的標(biāo)記中,很快就變得很難閱讀了,更重要的是,維護(hù)這樣的代碼將是一場災(zāi)難,尤其是在構(gòu)建大型應(yīng)用的時(shí)候。

JavaScript 模板解決方案(例如Handlebars.js 和Mustache)通常用于為視圖定義模板作為標(biāo)記(要么存儲在外部,要么存儲在腳本標(biāo)簽里面,使用自定義的類型例如text/template),標(biāo)記中包含有模板變量。變量可以使用變化的語法來分割(例如{{name}}),框架通常也足夠只能接受JSON格式的數(shù)據(jù)(模型可以轉(zhuǎn)化成JSOn格式),這樣我們只需要關(guān)心如何維護(hù)干凈的模型和干凈的模板。人們遭遇的絕大多數(shù)的苦差事都被框架本身所處理了。這樣做有大量的好處,尤其選擇是將模板存儲在外部的時(shí)候,這樣在構(gòu)建大型引應(yīng)用的時(shí)候可以是模板按照需要?jiǎng)討B(tài)加載。

下面我們可以看到兩個(gè)HTMP模板的例子。一個(gè)使用流行的Handlebar.js框架實(shí)現(xiàn),一個(gè)使用Underscore模板實(shí)現(xiàn)。

Handlebars.js

<li class="photo">
  <h2>{{caption}}</h2>
  <img class="source" src="{{src}}"/>
  <div class="meta-data">
    {{metadata}}
  </div>
</li>

Underscore.js Microtemplates

<li class="photo">
  <h2><%= caption %></h2>
  <img class="source" src="<%= src %>"/>
  <div class="meta-data">
    <%= metadata %>
  </div>
</li><span style="line-height:1.5;font-family:'sans serif', tahoma, verdana, helvetica;font-size:10pt;"></span>

請注意模板并不是它們自身的視圖,來自于Struts Model 2 架構(gòu)的開發(fā)者可能會感覺模板就是一個(gè)視圖,但并不是這樣的。視圖是一個(gè)觀察著模型的對象,并且讓可視的展現(xiàn)保持最新。模板也許是用一種聲明的方式指定部分甚至所有的視圖對象,因此它可能是從模板定制文檔生成的。

在經(jīng)典的web開發(fā)中,在單獨(dú)的視圖之間進(jìn)行導(dǎo)航需要利用到頁面刷新,然而也并不值得這樣做。而在單頁面Javascript應(yīng)用程序中,一旦數(shù)據(jù)通過ajax從服務(wù)器端獲取到了,并不需要任何這樣必要的刷新,就可以簡單的在同一個(gè)頁面渲染出一個(gè)新的視圖。

這里導(dǎo)航就降級為了“路由”的角色,用來輔助管理應(yīng)用程序狀態(tài)(例如,允許用戶用書簽標(biāo)記它們已經(jīng)瀏覽到的視圖)。然而,路由既不是MVC的一部分,也不在每一個(gè)類MVC框架中展現(xiàn)出來,在這一節(jié)中我將不深入詳細(xì)的討論它們。

總而言之,視圖是對我們的數(shù)據(jù)的一種可視化展現(xiàn)。

控制器

控制器是模型和視圖之間的中介,典型的職責(zé)是當(dāng)用戶操作視圖的時(shí)候同步更新模型。

在我們的照片廊應(yīng)用程序中,控制器會負(fù)責(zé)處理用戶通過對一個(gè)特定照片的視圖進(jìn)行編輯所造成改變,當(dāng)用戶完成編輯后,就更新一個(gè)特定的照片模型。

請記住滿足了MVC中的一種角色:針對視圖的策略模式的基礎(chǔ)設(shè)施。在策略模式方面,視圖在視圖的自由載量權(quán)方面代表了控制器。因此,那就是測試模式是如何工作的,視圖可以代表針對控制器的用戶事件,當(dāng)視圖看起來合適的時(shí)候。視圖也可以代表針對控制器的模型變更事件處理,當(dāng)視圖看起來合適的時(shí)候,但這并不是控制器的傳統(tǒng)角色。

大多數(shù)的Javascript MVC框架都受到了對"MVC"通常認(rèn)知的影響,而這種認(rèn)知是和控制器綁定在一起的.出現(xiàn)這種情況的原因各異,但在我的真實(shí)想法中,那是由于框架的作者一開始就將從服務(wù)器端的角度看待MVC,意識到它并不在客戶端進(jìn)行1:1的翻譯,而對MVC中的C進(jìn)行重新詮釋意在他們感覺更加有意義的事情.與此同在的問題在于它是主觀的,增加了理解經(jīng)典MVC模式的復(fù)雜度,當(dāng)然還有控制器在現(xiàn)代框架中的角色。

作為示例,讓我們來簡要回顧一下當(dāng)前流行的一種構(gòu)造框架Backbone.js其架構(gòu).Backbone包含了模型和視圖(某些東西同我們前面看到的類似),然而它實(shí)際上并沒有真正的控制器.它的視圖和路由行為同控制器有一點(diǎn)點(diǎn)類似,但它們自身實(shí)際上都不是控制器。

在這一方面,同官方文檔或者博客文章中可能提到的相左,Backbone既不是一個(gè)真正的MVC/MVP框架,也不是一個(gè)MVVM框架.事實(shí)上把它看做是用它自身的方式架構(gòu)方法的MV*家族中的一員,更加合適.當(dāng)然這沒有任何錯(cuò)誤的地方,但區(qū)分經(jīng)典MVC和MV*是重要的,我們應(yīng)該依靠前者的經(jīng)典語法來幫助理解后者。

Spine.js VS Backbone.js

Spine.js

我們現(xiàn)在知道傳統(tǒng)的控制器負(fù)責(zé)當(dāng)用戶更新視圖是同步更新模型.值得注意的一個(gè)有趣的地方是大多數(shù)時(shí)下流行的Javascript MVC/MV*框架在編寫的時(shí)候(Backbone)都沒有屬于它們自己的明確的控制器的概念。

因此,這對于我們從另一個(gè)MVC框架中體會到控制器實(shí)現(xiàn)的差異,并更進(jìn)一步的展現(xiàn)出控制如何扮演著非傳統(tǒng)的角色是很有用處的.對于這一點(diǎn),讓我們來看看來自于Spine.js的示例控制器。

在這個(gè)示例中,我們會有一個(gè)叫做PhotosController的控制器,用來管理應(yīng)用程序中的個(gè)人照片.它將確保當(dāng)視圖更新(例如,一個(gè)用戶編輯了照片的元數(shù)據(jù))時(shí),對應(yīng)的模型也會更新。

注意:我們并不會花大力氣研究Spine.js,而只是對它的控制器能做什么進(jìn)行一定程度的了解:

// Controllers in Spine are created by inheriting from Spine.Controller

var PhotosController = Spine.Controller.sub({ 

  init: function () {
    this.item.bind( "update" , this.proxy( this.render ));
    this.item.bind( "destroy", this.proxy( this.remove ));
  },

  render: function () {
    // Handle templating
    this.replace( $( "#photoTemplate" ).tmpl( this.item ) );
    return this;
  },

  remove: function () {
    this.el.remove();
    this.release();
  }
});

在Spine中,控制器被認(rèn)為是一個(gè)應(yīng)用程序的粘合劑,對DOM事件進(jìn)行添加和響應(yīng),渲染模板,還有確保視圖和模型保持同步(這在我們所知的控制器的上下文中起作用)。

我們在上面的example.js示例中所做的,是使用render()和remove()方法在更新和銷毀事件中設(shè)置偵聽器。當(dāng)一個(gè)照片條目獲得更新的時(shí)候,我們對視圖進(jìn)行重新渲染,以此反映對元數(shù)據(jù)的修改。類似的,如果照片從照片集中被刪除了,我們也會把它從視圖中移除。在render()函數(shù)中,我們使用Underscore微模板(通過_.template())來用ID #photoTemplate對一個(gè)Javascript模板進(jìn)行渲染。這樣會簡單的返回一個(gè)編輯了的HTML字符串用來填充photoEL的內(nèi)容。

這為我們提供了一個(gè)非常輕量級的,簡單的管理模型和視圖之間的變更的方法。

Backbone.js

后面的章節(jié)我們將會對Backbone和傳統(tǒng)MVC之間的區(qū)別進(jìn)行一下重新審視,但現(xiàn)在還是讓我們專注于控制器吧。

在Backbone中,控制器的責(zé)任一分為二,由Backbone.View和Backbone.Router共享.前段時(shí)間Backbone確曾有其屬于自己的Backbone.Controller,但是對這一組件的命名對于它所被使用的上下文環(huán)境中并沒有什么意義,后來它就被重新命名為Router了。

Router比控制器要負(fù)擔(dān)處理著更多一點(diǎn)點(diǎn)的責(zé)任,因?yàn)樗沟脼槟P徒壎ㄊ录?以及讓我們的視圖對DOM事件和渲染產(chǎn)生響應(yīng),成為可能.如Tim Branyen(另外一名基于Bocoup的Backbone貢獻(xiàn)者)在以前所指出的,為此完全擺脫不使用Backbone.Router是有可能的,因此一種考慮讓它使用Router范式的做法可能像下面這樣:

var PhotoRouter = Backbone.Router.extend({
  routes: { "photos/:id": "route" },

  route: function( id ) {
    var item = photoCollection.get( id );
    var view = new PhotoView( { model: item } );

    $('.content').html( view.render().el );
  }
});

總之,本節(jié)的重點(diǎn)是控制器管理著應(yīng)用程序中模型和視圖之間的邏輯和協(xié)作。

MVC給了我們什么?

MVC中關(guān)注分離的思想有利于對應(yīng)用程序中功能進(jìn)行更加簡單的模塊化,并且使得:

  • 整體的維護(hù)更加便利.當(dāng)需要對應(yīng)用程序進(jìn)行更新時(shí),到底這些改變是否是以數(shù)據(jù)為中心的,意味著對模型的修改還-有可能是控制器,或者僅僅是視覺的,意味著對視圖的修改,這一區(qū)分是非常清楚的。
  • 對模型和視圖的解耦意味著為業(yè)務(wù)邏輯編寫單元測試將會是更加直截了當(dāng)?shù)摹?/li>
  • 對底層模型和控制器的代碼解耦(即我們可能會取代使用的)在整個(gè)應(yīng)用程序中被淘汰了。
  • 依賴于應(yīng)用程序的體積和角色的分離,這種模塊化允許負(fù)責(zé)核心邏輯的開發(fā)者和工作于用戶界面的開發(fā)者同時(shí)進(jìn)行工作。

JavaScript中的Smalltalk-80 MVC

盡管當(dāng)今主流的JavaScript框架都嘗試引入MVC的模式,來更好地面對web應(yīng)用的開發(fā)。由Peter Michaux編寫的Maria.js ,是一個(gè)嘗試純正的Smalltalk-80的框架。其中,Model只是Model,View也只完成View應(yīng)該做的,controller則只負(fù)責(zé)控制。然后,一些開發(fā)人員認(rèn)為,MV*架構(gòu)更值得關(guān)注,如果你對純正的MVC架構(gòu)的JavaScript實(shí)現(xiàn)感興趣,這將是很好的參考。

更加深入的鉆研

在這本書的這一點(diǎn)上,我們應(yīng)該對MVC模式提供了些什么有了一個(gè)基礎(chǔ)的了解,然而仍然有一些值得去關(guān)注的非常美妙的信息。

GoF并不將MVC引述為一種設(shè)計(jì)模式,而是把它看做是構(gòu)建一個(gè)用戶界面的類的集合.按照他們的觀點(diǎn),它實(shí)際上是三種經(jīng)典設(shè)計(jì)模式的變異組合:觀察者模式,策略模式和組件模式.依賴于框架中的MVC如何實(shí)現(xiàn),它也可能會使用工廠和模板模式.GoF Book提到這些模式在使用MVC工作時(shí)是非常有用的附加功能。

如我們所討論的,模型代表應(yīng)用程序的數(shù)據(jù),而視圖則是用戶在屏幕上看到的被展現(xiàn)出來的東西.如此,MVC它的一些核心的通訊就要依賴于觀察者模式(令人驚奇的是,一些相關(guān)的內(nèi)容在許多關(guān)于MVC模式的書籍并沒有被涵蓋到).當(dāng)模型被改變時(shí),它會通知觀察者(視圖)一些東西已經(jīng)被更新了——這也許是MVC中最重要的關(guān)系。觀察者的這一特性也是實(shí)現(xiàn)將多個(gè)視圖連結(jié)到同一個(gè)模型的基礎(chǔ)。

對于那些對MVC解耦特性想了解更多的開發(fā)者(這再一次依賴于特定的實(shí)現(xiàn)),這一模式的目標(biāo)之一就是幫助去實(shí)現(xiàn)一個(gè)主體(數(shù)據(jù)對象)和它的觀察者之間的一對多關(guān)系的定義。當(dāng)一個(gè)主體發(fā)生改變的時(shí)候,它的觀察者也會被更新。視圖和控制器有一種稍微不同的關(guān)系.控制器協(xié)助視圖對不同的用戶輸入做出響應(yīng),這也是一個(gè)策略模式的例子。

總結(jié)

回顧完經(jīng)典的MVC模式以后,我們現(xiàn)在應(yīng)該理解了它是如何允許我們對一個(gè)應(yīng)用程序中的各個(gè)關(guān)注點(diǎn)進(jìn)行清晰地的區(qū)分.我們現(xiàn)在也應(yīng)該感恩于Javascript MVC框架在它們對MVC模式的詮釋中是如何的不同,而其對變異也是相當(dāng)開放的,仍然分享著其原生模式已經(jīng)提供的其中一些基礎(chǔ)概念。

當(dāng)審視一個(gè)新的Javas MVC/MV*框架時(shí),請記住——回過頭去考察考察它如何選擇相近的架構(gòu)(特別的,它支持實(shí)現(xiàn)了模型,視圖,控制器或者其它的一些可選特性)可能會有些用處,因?yàn)檫@樣能夠更好的幫助我們深入了解這一框架預(yù)計(jì)需要被如何拿來使用。

上一篇:代理模式下一篇:亨元模式