組合模式可以理解為樹狀結構,因此組合模式適合對大批對象的操作,特別是層次結構分明的,下面我們就來看看號稱面向對象的JavaScript設計模式開發中組合模式的使用教程
我們平常開發過程中,一定會遇到這種情況:同時處理簡單對象和由簡單對象組成的複雜對象,這些簡單對象和復雜對象會組合成樹形結構,在客戶端對其處理的時候要保持一致性。例如電商網站中的產品訂單,每一張產品訂單可能有多個子訂單組合,例如操作系統的資料夾,每個資料夾有多個子資料夾或文件,我們作為使用者複製,刪除等操作時,不管是資料夾還是文件,對我們操作者來說是一樣的。在這種場景下,就非常適合使用組合模式來實現。
基本知識
組合模式:將物件組合成樹狀結構以表示「部分-整體」的層次結構,組合模式使得使用者對單一物件和組合物件的使用具有一致性。
組合模式主要有三個角色:
(1)抽像元件(Component):抽象類,主要定義了參與組合的物件的公共介面
(2)子物件(Leaf):組成組合對象的最基本物件
(3)組合物件(Composite):由子物件組合起來的複雜物件
理解組合模式的關鍵是要理解組合模式對單一物件和組合物件使用的一致性,我們接下來說說組合模式的實現加深理解。
組合模式算是為在頁面動態創建UI量身定做的,你可以只使用一條命=命令為許多對像初始化一些複雜的或者遞歸的操作.組合模式提供了兩個有點:
(1 )允許你將一組物件當成特定的物件.組合物件(A composite)和組成它的子物件實現相同的操作.對組合物件執行某一個操作將會使該物件下的所有子物件執行相同的操作.因此你不僅可以無縫的替換單一物件為一組物件集合,反過來也一樣.這些獨立的物件之間即所謂鬆散耦合的.
(2)組合模式會將子物件集組合成樹結構並且允許遍歷整個樹.這樣可以隱藏內部實現並且允許你以任意的方式組織子對象.這個對象(組合對象)的任何代碼將不會依賴內部子對象的實現.
組合模式的實作
(1)最簡單的組合模式
#HTML文件的DOM結構就是天生的樹狀結構,最基本的元素醉成DOM樹,最終形成DOM文檔,非常適用組合模式。
我們常用的jQuery類別庫,其中組合模式的應用更是頻繁,例如經常有下列程式碼實作:
$(".test").addClass("noTest").remove("test");
這句簡單的程式碼就是取得class包含test的元素,然後進行addClass和removeClass處理,其中不論$(“.test”)是一個元素,還是多個元素,最終都是透過統一的addClass和removeClass介面進行呼叫。
我們簡單模擬addClass的實作:
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("p3"), "test"); addClass(document.querySelectorAll(".p"), "test");
這段程式碼簡單的模擬了addClass的實作(暫不考慮相容性和通用性),很簡單地先判斷節點類型,然後根據不同類型添加className。對於NodeList或者是Node來說,客戶端呼叫都是同樣的使用了addClass這個接口,這個是組合模式的最基本的思想,使部分和整體的使用具有一致性。
(2)典型的例子
在前面我們提到一個典型的例子:產品訂單包含多個產品子訂單,多個產品子訂單組成一個複雜的產品訂單。由於Javascript語言的特性,我們將組合模式的三個角色簡化成2個角色:
(1)子物件:在這個範例中,子物件就是產品子訂單
(2)組合物件:這裡就是產品的總訂單
假設我們開發一個旅遊產品網站,其中包含機票和飯店兩種子產品,我們定義了子物件如下:
function FlightOrder() { } FlightOrder.prototyp.create = function () { console.log("flight order created"); } function HotelOrder() { } HotelOrder.prototype.create = function () { console.log("hotel order created"); }
上面的程式碼定義了兩個類別:機票訂單類別和飯店訂單類,每個類別都有各自的訂單建立方法。
接下來我們建立一個總訂單類別:
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個成員:訂單列表,新增訂單的方法,建立訂單的方法。
在客戶端使用的時候如下:
var flight = new FlightOrder(); flight.create(); var orders = new TotalOrders(); orders.addOrder(new FlightOrder()); orders.addOrder(new HotelOrder()); orders.create();
客戶端呼叫展示了兩種方式,一種是單一的創建機票訂單,一種是創建多張訂單,但最終都是透過create方法進行創建,這是一個很典型的組合模式的應用場景。
總結組合模式並不難理解,它主要解決的是單一物件和組合物件在使用方式上的一致性問題。如果物件具有明顯的層次結構並且想要統一地使用它們,這就非常適合使用組合模式。在Web開發中,這種層次結構非常常見,很適合使用組合模式,尤其是對於JS來說,不用拘泥於傳統物件導向語言的形式,靈活地利用JS語言的特性,達到對部分和整體使用的一致性。
(1)使用組合模式的場景在遇到下面兩種情況的時候才使用組合模式
A.含有某種層級結構的物件集合(具體結構在開發過程中無法確定)
B.希望對這些物件或其中的某些物件執行某種操作
(2)組合模式的缺點因為組合物件的任何操作都會對所有的子對象調用同樣的操作,所以當組合的結構很大時會有效能問題。還有就是使用組合模式封裝HTML時要選擇適合的標籤,例如table就不能用於組合模式,葉子節點不明顯
上面是我整理給大家的,希望今後會對大家有幫助。
相關文章:
設計模式中的facade外觀模式在JavaScript開發中的運用(進階篇)
詳細解讀在JavaScript中實作設計模式中的適配器模式的方法(圖文教學)
Adapter適配器模式在JavaScript設計模式程式設計中的運用總結(圖文教學)
#以上是JavaScript設計模式開發中組合模式的使用教學(高階篇)的詳細內容。更多資訊請關注PHP中文網其他相關文章!