欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript設(shè)計模式開發(fā)中組合模式的使用教程

 更新時間:2016年05月18日 10:51:53   作者:狼狼的藍(lán)胖子  
組合模式可以理解為樹狀結(jié)構(gòu),因此組合模式適合對大批對象的操作,特別是層次結(jié)構(gòu)分明的,下面我們就來看看號稱面向?qū)ο蟮腏avaScript設(shè)計模式開發(fā)中組合模式的使用教程

我們平時開發(fā)過程中,一定會遇到這種情況:同時處理簡單對象和由簡單對象組成的復(fù)雜對象,這些簡單對象和復(fù)雜對象會組合成樹形結(jié)構(gòu),在客戶端對其處理的時候要保持一致性。比如電商網(wǎng)站中的產(chǎn)品訂單,每一張產(chǎn)品訂單可能有多個子訂單組合,比如操作系統(tǒng)的文件夾,每個文件夾有多個子文件夾或文件,我們作為用戶對其進(jìn)行復(fù)制,刪除等操作時,不管是文件夾還是文件,對我們操作者來說是一樣的。在這種場景下,就非常適合使用組合模式來實現(xiàn)。

基本知識

組合模式:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對單個對象和組合對象的使用具有一致性。
組合模式主要有三個角色:
(1)抽象組件(Component):抽象類,主要定義了參與組合的對象的公共接口
(2)子對象(Leaf):組成組合對象的最基本對象
(3)組合對象(Composite):由子對象組合起來的復(fù)雜對象
理解組合模式的關(guān)鍵是要理解組合模式對單個對象和組合對象使用的一致性,我們接下來說說組合模式的實現(xiàn)加深理解。
組合模式算是為在頁面動態(tài)創(chuàng)建UI量身定做的,你可以只使用一條命=命令為許多對象初始化一些復(fù)雜的或者遞歸的操作.組合模式提供了兩個有點:
(1)允許你將一組對象當(dāng)成特定的對象.組合對象(A composite)和組成它的子對象實現(xiàn)相同的操作.對組合對象執(zhí)行某一個操作將會使該對象下的所有子對象執(zhí)行相同的操作.因此你不僅可以無縫的替換單個對象為一組對象集合,反過來也一樣.這些獨立的對象之間即所謂松散耦合的.
(2)組合模式會將子對象集組合成樹結(jié)構(gòu)并且允許遍歷整個樹.這樣可以隱藏內(nèi)部實現(xiàn)并且允許你以任意的方式組織子對象.這個對象(組合對象)的任何代碼將不會依賴內(nèi)部子對象的實現(xiàn).

組合模式的實現(xiàn)

(1)最簡單的組合模式

HTML文檔的DOM結(jié)構(gòu)就是天生的樹形結(jié)構(gòu),最基本的元素醉成DOM樹,最終形成DOM文檔,非常適用適用組合模式。
我們常用的jQuery類庫,其中組合模式的應(yīng)用更是頻繁,例如經(jīng)常有下列代碼實現(xiàn):

$(".test").addClass("noTest").remove("test");

這句簡單的代碼就是獲取class包含test的元素,然后進(jìn)行addClass和removeClass處理,其中不論$(“.test”)是一個元素,還是多個元素,最終都是通過統(tǒng)一的addClass和removeClass接口進(jìn)行調(diào)用。
我們簡單模擬一下addClass的實現(xiàn):

var addClass = function (eles, className) {
  if (eles instanceof NodeList) {
    for (var i = 0, length = eles.length; i < length; i++) {
      eles[i].nodeType === 1 && (eles[i].className += (' ' + className + ' '));
    }
  }
  else if (eles instanceof Node) {
    eles.nodeType === 1 && (eles.className += (' ' + className + ' '));
  }
  else {
    throw "eles is not a html node";
  }
}
addClass(document.getElementById("div3"), "test");
addClass(document.querySelectorAll(".div"), "test");

這段代碼簡單的模擬了addClass的實現(xiàn)(暫不考慮兼容性和通用性),很簡單地先判斷節(jié)點類型,然后根據(jù)不同類型添加className。對于NodeList或者是Node來說,客戶端調(diào)用都是同樣的使用了addClass這個接口,這個就是組合模式的最基本的思想,使部分和整體的使用具有一致性。

(2)典型的例子

前面我們提到一個典型的例子:產(chǎn)品訂單包含多個產(chǎn)品子訂單,多個產(chǎn)品子訂單組成一個復(fù)雜的產(chǎn)品訂單。由于Javascript語言的特性,我們將組合模式的三個角色簡化成2個角色:
(1)子對象:在這個例子中,子對象就是產(chǎn)品子訂單
(2)組合對象:這里就是產(chǎn)品的總訂單
假設(shè)我們開發(fā)一個旅游產(chǎn)品網(wǎng)站,其中包含機(jī)票和酒店兩種子產(chǎn)品,我們定義了子對象如下:

function FlightOrder() { }
FlightOrder.prototyp.create = function () {
  console.log("flight order created");
}
function HotelOrder() { }
HotelOrder.prototype.create = function () {
  console.log("hotel order created");
}

上面的代碼定義了兩個類:機(jī)票訂單類和酒店訂單類,每個類都有各自的訂單創(chuàng)建方法。
接下來我們創(chuàng)建一個總訂單類:

function TotalOrders() {
  this.orderList = [];
}
TotalOrders.prototype.addOrder = function (order) {
  this.orderList.push(order);
}
TotalOrders.prototype.create = function (order) {
  for (var i = 0, length = this.orderList.length; i < length; i++) {
    this.orderList[i].create();
  }
}

這個對象主要有3個成員:訂單列表,添加訂單的方法,創(chuàng)建訂單的方法。
在客戶端使用的時候如下:

var flight = new FlightOrder();
flight.create();

var orders = new TotalOrders();
orders.addOrder(new FlightOrder());
orders.addOrder(new HotelOrder());
orders.create();

客戶端調(diào)用展示了兩種方式,一種是單一的創(chuàng)建機(jī)票訂單,一種是創(chuàng)建多張訂單,但最終都是通過create方法進(jìn)行創(chuàng)建,這就是一個很典型的組合模式的應(yīng)用場景。

總結(jié)
組合模式并不難理解,它主要解決的是單一對象和組合對象在使用方式上的一致性問題。如果對象具有明顯的層次結(jié)構(gòu)并且想要統(tǒng)一地使用它們,這就非常適合使用組合模式。在Web開發(fā)中,這種層次結(jié)構(gòu)非常常見,很適合使用組合模式,尤其是對于JS來說,不用拘泥于傳統(tǒng)面向?qū)ο笳Z言的形式,靈活地利用JS語言的特性,達(dá)到對部分和整體使用的一致性。
(1)使用組合模式的場景
在遇到下面兩種情況的時候才使用組合模式
A.含有某種層級結(jié)構(gòu)的對象集合(具體結(jié)構(gòu)在開發(fā)過程中無法確定)
B.希望對這些對象或者其中的某些對象執(zhí)行某種操作
(2)組合模式的缺點
因為組合對象的任何操作都會對所有的子對象調(diào)用同樣的操作,所以當(dāng)組合的結(jié)構(gòu)很大時會有性能問題。還有就是使用組合模式封裝HTML時要選擇合適的標(biāo)簽,比如table就不能用于組合模式,葉子節(jié)點不明顯

相關(guān)文章

  • JavaScript中字符串拼接的基本方法

    JavaScript中字符串拼接的基本方法

    這篇文章主要介紹了JavaScript中字符串拼接的基本方法,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-07-07
  • JavaScript的Date()方法使用詳解

    JavaScript的Date()方法使用詳解

    這篇文章主要介紹了JavaScript的Date()方法使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • 有關(guān)于JS構(gòu)造函數(shù)的重載和工廠方法

    有關(guān)于JS構(gòu)造函數(shù)的重載和工廠方法

    有關(guān)于JS構(gòu)造函數(shù)的重載和工廠方法,對此有需要的朋友,參考一下。
    2013-04-04
  • 原始的js代碼和jquery對比體會

    原始的js代碼和jquery對比體會

    在我們自己處理的時候,甚至是這么簡單的任務(wù)在不使用jquery的時候都會變得復(fù)雜,通過下面我們可以清晰的看到使用query代碼比原生js代碼寫起來更容易
    2013-09-09
  • js數(shù)組常用最重要的方法

    js數(shù)組常用最重要的方法

    本篇文章給大家整理了JS數(shù)組中最重要的常用方法,本次整理的是小編認(rèn)為大家在使用中最常用也是最重要的方法,一起學(xué)習(xí)下。
    2018-02-02
  • javascript之Boolean類型對象

    javascript之Boolean類型對象

    本文主要介紹javascript中的Boolean類型對象,Boolean對象非常簡單,卻非常有用,希望能給大家做一個參考。
    2016-06-06
  • JavaScript 基礎(chǔ)篇之對象、數(shù)組使用介紹(三)

    JavaScript 基礎(chǔ)篇之對象、數(shù)組使用介紹(三)

    對象我們在前面也簡單介紹過,它是一種將多個數(shù)據(jù)值集中在一個單元的東西,使用名字來存取,它是一個無序的屬性集合
    2012-04-04
  • javascript中的3種繼承實現(xiàn)方法

    javascript中的3種繼承實現(xiàn)方法

    這篇文章主要介紹了javascript中的3種繼承實現(xiàn)方法,包括使用Object.create實現(xiàn)類式繼承、使用utilities工具包自帶的util.inherites、使用extends關(guān)鍵字,非常的實用,希望對大家了解javascript繼承能夠有所幫助
    2016-01-01
  • JS聲明變量背后的編譯原理剖析

    JS聲明變量背后的編譯原理剖析

    只要是寫過點JS代碼,很簡單一個var 就完事了。那對于JS編譯器背后它又發(fā)生了什么呢?那就一步步通過代碼來講起,需要了解的朋友研究下哦
    2012-12-12
  • Node.js生成HttpStatusCode輔助類發(fā)布到npm

    Node.js生成HttpStatusCode輔助類發(fā)布到npm

    本篇文章小編為大家介紹利用Node.js為Node.js生成HttpStatusCode輔助類并發(fā)布到npm,有需要的朋友可以參考一下
    2013-04-04

最新評論