JavaScript設(shè)計(jì)模式開(kāi)發(fā)中組合模式的使用教程
來(lái)源:易賢網(wǎng) 閱讀:754 次 日期:2016-06-27 15:15:43
溫馨提示:易賢網(wǎng)小編為您整理了“JavaScript設(shè)計(jì)模式開(kāi)發(fā)中組合模式的使用教程”,方便廣大網(wǎng)友查閱!

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

基本知識(shí)

組合模式:將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

組合模式主要有三個(gè)角色:

(1)抽象組件(Component):抽象類(lèi),主要定義了參與組合的對(duì)象的公共接口

(2)子對(duì)象(Leaf):組成組合對(duì)象的最基本對(duì)象

(3)組合對(duì)象(Composite):由子對(duì)象組合起來(lái)的復(fù)雜對(duì)象

理解組合模式的關(guān)鍵是要理解組合模式對(duì)單個(gè)對(duì)象和組合對(duì)象使用的一致性,我們接下來(lái)說(shuō)說(shuō)組合模式的實(shí)現(xiàn)加深理解。

組合模式算是為在頁(yè)面動(dòng)態(tài)創(chuàng)建UI量身定做的,你可以只使用一條命=命令為許多對(duì)象初始化一些復(fù)雜的或者遞歸的操作.組合模式提供了兩個(gè)有點(diǎn):

(1)允許你將一組對(duì)象當(dāng)成特定的對(duì)象.組合對(duì)象(A composite)和組成它的子對(duì)象實(shí)現(xiàn)相同的操作.對(duì)組合對(duì)象執(zhí)行某一個(gè)操作將會(huì)使該對(duì)象下的所有子對(duì)象執(zhí)行相同的操作.因此你不僅可以無(wú)縫的替換單個(gè)對(duì)象為一組對(duì)象集合,反過(guò)來(lái)也一樣.這些獨(dú)立的對(duì)象之間即所謂松散耦合的.

(2)組合模式會(huì)將子對(duì)象集組合成樹(shù)結(jié)構(gòu)并且允許遍歷整個(gè)樹(shù).這樣可以隱藏內(nèi)部實(shí)現(xiàn)并且允許你以任意的方式組織子對(duì)象.這個(gè)對(duì)象(組合對(duì)象)的任何代碼將不會(huì)依賴內(nèi)部子對(duì)象的實(shí)現(xiàn).

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

(1)最簡(jiǎn)單的組合模式

HTML文檔的DOM結(jié)構(gòu)就是天生的樹(shù)形結(jié)構(gòu),最基本的元素醉成DOM樹(shù),最終形成DOM文檔,非常適用適用組合模式。

我們常用的jQuery類(lèi)庫(kù),其中組合模式的應(yīng)用更是頻繁,例如經(jīng)常有下列代碼實(shí)現(xiàn):

?

1

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

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

我們簡(jiǎn)單模擬一下addClass的實(shí)現(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");

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

(2)典型的例子

前面我們提到一個(gè)典型的例子:產(chǎn)品訂單包含多個(gè)產(chǎn)品子訂單,多個(gè)產(chǎn)品子訂單組成一個(gè)復(fù)雜的產(chǎn)品訂單。由于Javascript語(yǔ)言的特性,我們將組合模式的三個(gè)角色簡(jiǎn)化成2個(gè)角色:

(1)子對(duì)象:在這個(gè)例子中,子對(duì)象就是產(chǎn)品子訂單

(2)組合對(duì)象:這里就是產(chǎn)品的總訂單

假設(shè)我們開(kāi)發(fā)一個(gè)旅游產(chǎn)品網(wǎng)站,其中包含機(jī)票和酒店兩種子產(chǎn)品,我們定義了子對(duì)象如下:

function FlightOrder() { }

FlightOrder.prototyp.create = function () {

  console.log("flight order created");

}

function HotelOrder() { }

HotelOrder.prototype.create = function () {

  console.log("hotel order created");

}

上面的代碼定義了兩個(gè)類(lèi):機(jī)票訂單類(lèi)和酒店訂單類(lèi),每個(gè)類(lèi)都有各自的訂單創(chuàng)建方法。

接下來(lái)我們創(chuàng)建一個(gè)總訂單類(lèi):

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();

  }

}

這個(gè)對(duì)象主要有3個(gè)成員:訂單列表,添加訂單的方法,創(chuàng)建訂單的方法。

在客戶端使用的時(shí)候如下:

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)建多張訂單,但最終都是通過(guò)create方法進(jìn)行創(chuàng)建,這就是一個(gè)很典型的組合模式的應(yīng)用場(chǎng)景。

總結(jié)

組合模式并不難理解,它主要解決的是單一對(duì)象和組合對(duì)象在使用方式上的一致性問(wèn)題。如果對(duì)象具有明顯的層次結(jié)構(gòu)并且想要統(tǒng)一地使用它們,這就非常適合使用組合模式。在Web開(kāi)發(fā)中,這種層次結(jié)構(gòu)非常常見(jiàn),很適合使用組合模式,尤其是對(duì)于JS來(lái)說(shuō),不用拘泥于傳統(tǒng)面向?qū)ο笳Z(yǔ)言的形式,靈活地利用JS語(yǔ)言的特性,達(dá)到對(duì)部分和整體使用的一致性。

(1)使用組合模式的場(chǎng)景

在遇到下面兩種情況的時(shí)候才使用組合模式

A.含有某種層級(jí)結(jié)構(gòu)的對(duì)象集合(具體結(jié)構(gòu)在開(kāi)發(fā)過(guò)程中無(wú)法確定)

B.希望對(duì)這些對(duì)象或者其中的某些對(duì)象執(zhí)行某種操作

(2)組合模式的缺點(diǎn)

因?yàn)榻M合對(duì)象的任何操作都會(huì)對(duì)所有的子對(duì)象調(diào)用同樣的操作,所以當(dāng)組合的結(jié)構(gòu)很大時(shí)會(huì)有性能問(wèn)題。還有就是使用組合模式封裝HTML時(shí)要選擇合適的標(biāo)簽,比如table就不能用于組合模式,葉子節(jié)點(diǎn)不明顯

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門(mén)公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類(lèi)型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專(zhuān)用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專(zhuān)用圖標(biāo)