JavaScript 設計模式之組合模式解析

來源:互聯網
上載者:User

怎麼說呢?!就像是動物(組合對象)一樣,當它生下後代(葉對象)時,它的後代就有了某種功能(比如:挖洞,聽力好等等);也像是一棵樹,它有一個根(組合對象)然後是從這個棵樹向外冒出的其他枝杆(組合對象)以及從這些枝杆又向外長的葉子(葉對象)。換句話說,就是當祖先已經有了,那麼只要從這個祖先衍生出來的其他孩子(包括這個祖先下的其他組合對象)已經就具備了某種功能,看上去貌似又有些像是繼承。“組合模式”在組合對象的層次體系中有兩種類型的對象:葉對象和組合對象。組合模式擅長於對大批對象進行操作。
“組合模式”就是在做一個項目的時候,我們要把在這個項目中即將出現的方法都在組合對象中定義(包括葉對象中的方法),而它們的葉對象將會繼承組合對象。當組合對象被執行個體化後其葉對象的方法也相應地被執行個體化了。可能我說的有些亂,下面就用一個例子來說明吧。
“組合模式”是一種專為建立Web上的動態使用者介面而量身定製的模式。使用這種模式,可以用一條命令在多個對象上激發複雜的或遞迴的行為。
使用“組合模式”可以為我們帶來兩大好處:
1、可以用同樣的方法處理對象的集合與其中的特定子物件。
2、可以用來把一批子物件組織成樹形結構,並且使整棵樹都可以被遍曆。
只有同時具備以下兩個條件進才適合使用組合模式:
1、存在一批組織成某處層次體系的對象(具體結構可能在開發期間無法知道)。
2、希望對這批對象或其中的一部分對象實話一個操作。
下面看一下樣本:
具體要求是做一個圖片庫且可以有選擇地隱藏或顯示圖片庫的特定部分。這可能是單獨圖片,也可能是圖片庫。現在就需要兩個類來完成這個功能:用作圖片庫的組合對象類和用於圖片本身的葉對象類,代碼如下:
在上面的代碼中,首先定義的是組合對象類和葉對象類應該實現的介面。除了常規的組合遠景一分錢上,這些類要怕硬欺軟 操作只包括hide和show。接下來我們定義葉對象。葉對象實現hide和show,代碼如下: 複製代碼 代碼如下:var Composite = new Interface('Composite', ['add', 'remove', 'getChild']); // 檢查組合對象Composite應該具備的方法
var GalleryItem = new Interface('GalleryItem', ['hide', 'show']); // 檢查組合對象GalleryItem應該具備的方法
// DynamicGallery Class
var DynamicGallery = function(id){ // 實現Composite,GalleryItem組合對象類
this.children = [];

this.element = document.createElement('div');
this.element.id = id;
this.element.className = 'dynamic-gallery';
}
DynamicGallery.prototype = {
// 實現Composite組合對象介面
add : function(child){
Interface.ensureImplements(child, Composite, DynamicGallery);
this.children.push(child);
this.element.appendChild(child.getElement());
},
remove : function(child){
for(var node, i = 0; node = this.getChild(i); i++){
if(node == child){
this.children.splice(i, 1);
break;
}
}
this.element.removeChild(child.getElement());
},
getChild : function(i){
return this.children[i];
},
// 實現DynamicGallery組合對象介面
hide : function(){
for(var node, i = 0; node = this.getChild(i); i++){
node.hide();
}
this.element.style.display = 'none';
},
show : functioln(){
this.element.style.display = 'block';
for(var node, i = 0; node = getChild(i); i++){
node.show();
}
},
// 協助方法
getElement : function(){
return this.element;
}
}

以下是設定葉對象的相應方法: 複製代碼 代碼如下:// GalleryImage class
var GalleryImage = function(src){ // 實現Composite和GalleryItem組合對象中所定義的方法
this.element = document.createElement('img');
this.element.className = 'gallery-image';
this.element.src = src;
}
GalleryImage.prototype = {

// 實現Composite介面
// 這些是葉結點,所以我們不用實現這些方法,我們只需要定義即可
add : function(){},
remove : function(){},
getChild : function(){},
// 實現GalleryItem介面
hide : function(){
this.element.style.display = 'none';
},
show : function(){
this.element.style.display = '';
},
// 協助方法
getElement : function(){
return this.element;
}
}

這是一個示範組合模式的工作方式的例子。每個類都很簡單,但由於有了這樣一種層次體系,我們就可以執行一些複雜操作。GalleryImage類的建構函式會建立一個image元素。這個類定義中的其餘部分由空的組合對象方法(因為這是葉結點)和GalleryItem要求的操作組成。現在我們可以使用這兩個類來管理圖片: 複製代碼 代碼如下:var topGallery = new DynamicGallery('top-gallery');
topGallery.add(new GalleryImage('/img/image-1.jpg'));
topGallery.add(new GalleryImage('/img/image-2.jpg'));
topGallery.add(new GalleryImage('/img/image-3.jpg'));
var vacationPhotos = new DyamicGallery('vacation-photos');
for(var i = 0, i < 30; i++){
vacationPhotos.add(new GalleryImage('/img/vac/image-' + i + '.jpg'));
}
topGallery.add(vacationPhotos);
topGallery.show();
vacationPhotos.hide();

組合模式之利,使用組合模式,簡單的操作也能產生複雜的結果。不必編寫大師手工遍曆數組或其他資料結構的粘合代碼,只需對最頂層的對象執行操作,主每一個子物件自己傳遞這個操作即可。這對於那些再三執行的操作尤其有用。在組合模式中,各個對象之間的耦合非常鬆散。每當對頂層組合對象執行一個操作時,實際上是在對整個結構進行嘗試優先的搜尋以尋找節點。
組合模式之弊,由於對組合模式調用的任何操作都會被頗佳北至 它的所有子物件,如果這個層次體系很大的話,系統的效能將會受到影響。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.