JavaScript 設計模式之組合模式解析
更新時間:2010年04月09日 11:07:37 作者:
“組合模式”顧名思意就是將多種實現(xiàn)組合在一起而達到牽一處而動全身的效果。
怎么說呢?!就像是動物(組合對象)一樣,當它生下后代(葉對象)時,它的后代就有了某種功能(比如:挖洞,聽力好等等);也像是一棵樹,它有一個根(組合對象)然后是從這個棵樹向外冒出的其他枝桿(組合對象)以及從這些枝桿又向外長的葉子(葉對象)。換句話說,就是當祖先已經(jīng)有了,那么只要從這個祖先衍生出來的其他孩子(包括這個祖先下的其他組合對象)已經(jīng)就具備了某種功能,看上去貌似又有些像是繼承。“組合模式”在組合對象的層次體系中有兩種類型的對象:葉對象和組合對象。組合模式擅長于對大批對象進行操作。
“組合模式”就是在做一個項目的時候,我們要把在這個項目中即將出現(xiàn)的方法都在組合對象中定義(包括葉對象中的方法),而它們的葉對象將會繼承組合對象。當組合對象被實例化后其葉對象的方法也相應地被實例化了。可能我說的有些亂,下面就用一個例子來說明吧。
“組合模式”是一種專為創(chuàng)建Web上的動態(tài)用戶界面而量身定制的模式。使用這種模式,可以用一條命令在多個對象上激發(fā)復雜的或遞歸的行為。
使用“組合模式”可以為我們帶來兩大好處:
1、可以用同樣的方法處理對象的集合與其中的特定子對象。
2、可以用來把一批子對象組織成樹形結構,并且使整棵樹都可以被遍歷。
只有同時具備以下兩個條件進才適合使用組合模式:
1、存在一批組織成某處層次體系的對象(具體結構可能在開發(fā)期間無法知道)。
2、希望對這批對象或其中的一部分對象實話一個操作。
下面看一下示例:
具體要求是做一個圖片庫且可以有選擇地隱藏或顯示圖片庫的特定部分。這可能是單獨圖片,也可能是圖片庫?,F(xiàn)在就需要兩個類來完成這個功能:用作圖片庫的組合對象類和用于圖片本身的葉對象類,代碼如下:
在上面的代碼中,首先定義的是組合對象類和葉對象類應該實現(xiàn)的接口。除了常規(guī)的組合遠景一分錢上,這些類要怕硬欺軟 操作只包括hide和show。接下來我們定義葉對象。葉對象實現(xiàn)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){ // 實現(xiàn)Composite,GalleryItem組合對象類
this.children = [];
this.element = document.createElement('div');
this.element.id = id;
this.element.className = 'dynamic-gallery';
}
DynamicGallery.prototype = {
// 實現(xiàn)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];
},
// 實現(xiàn)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){ // 實現(xiàn)Composite和GalleryItem組合對象中所定義的方法
this.element = document.createElement('img');
this.element.className = 'gallery-image';
this.element.src = src;
}
GalleryImage.prototype = {
// 實現(xiàn)Composite接口
// 這些是葉結點,所以我們不用實現(xiàn)這些方法,我們只需要定義即可
add : function(){},
remove : function(){},
getChild : function(){},
// 實現(xiàn)GalleryItem接口
hide : function(){
this.element.style.display = 'none';
},
show : function(){
this.element.style.display = '';
},
// 幫助方法
getElement : function(){
return this.element;
}
}
這是一個演示組合模式的工作方式的例子。每個類都很簡單,但由于有了這樣一種層次體系,我們就可以執(zhí)行一些復雜操作。GalleryImage類的構造函數(shù)會創(chuàng)建一個image元素。這個類定義中的其余部分由空的組合對象方法(因為這是葉結點)和GalleryItem要求的操作組成。現(xiàn)在我們可以使用這兩個類來管理圖片:
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();
組合模式之利,使用組合模式,簡單的操作也能產(chǎn)生復雜的結果。不必編寫大師手工遍歷數(shù)組或其他數(shù)據(jù)結構的粘合代碼,只需對最頂層的對象執(zhí)行操作,主每一個子對象自己傳遞這個操作即可。這對于那些再三執(zhí)行的操作尤其有用。在組合模式中,各個對象之間的耦合非常松散。每當對頂層組合對象執(zhí)行一個操作時,實際上是在對整個結構進行嘗試優(yōu)先的搜索以查找節(jié)點。
組合模式之弊,由于對組合模式調(diào)用的任何操作都會被頗佳北至 它的所有子對象,如果這個層次體系很大的話,系統(tǒng)的性能將會受到影響。
“組合模式”就是在做一個項目的時候,我們要把在這個項目中即將出現(xiàn)的方法都在組合對象中定義(包括葉對象中的方法),而它們的葉對象將會繼承組合對象。當組合對象被實例化后其葉對象的方法也相應地被實例化了。可能我說的有些亂,下面就用一個例子來說明吧。
“組合模式”是一種專為創(chuàng)建Web上的動態(tài)用戶界面而量身定制的模式。使用這種模式,可以用一條命令在多個對象上激發(fā)復雜的或遞歸的行為。
使用“組合模式”可以為我們帶來兩大好處:
1、可以用同樣的方法處理對象的集合與其中的特定子對象。
2、可以用來把一批子對象組織成樹形結構,并且使整棵樹都可以被遍歷。
只有同時具備以下兩個條件進才適合使用組合模式:
1、存在一批組織成某處層次體系的對象(具體結構可能在開發(fā)期間無法知道)。
2、希望對這批對象或其中的一部分對象實話一個操作。
下面看一下示例:
具體要求是做一個圖片庫且可以有選擇地隱藏或顯示圖片庫的特定部分。這可能是單獨圖片,也可能是圖片庫?,F(xiàn)在就需要兩個類來完成這個功能:用作圖片庫的組合對象類和用于圖片本身的葉對象類,代碼如下:
在上面的代碼中,首先定義的是組合對象類和葉對象類應該實現(xiàn)的接口。除了常規(guī)的組合遠景一分錢上,這些類要怕硬欺軟 操作只包括hide和show。接下來我們定義葉對象。葉對象實現(xiàn)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){ // 實現(xiàn)Composite,GalleryItem組合對象類
this.children = [];
this.element = document.createElement('div');
this.element.id = id;
this.element.className = 'dynamic-gallery';
}
DynamicGallery.prototype = {
// 實現(xiàn)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];
},
// 實現(xiàn)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){ // 實現(xiàn)Composite和GalleryItem組合對象中所定義的方法
this.element = document.createElement('img');
this.element.className = 'gallery-image';
this.element.src = src;
}
GalleryImage.prototype = {
// 實現(xiàn)Composite接口
// 這些是葉結點,所以我們不用實現(xiàn)這些方法,我們只需要定義即可
add : function(){},
remove : function(){},
getChild : function(){},
// 實現(xiàn)GalleryItem接口
hide : function(){
this.element.style.display = 'none';
},
show : function(){
this.element.style.display = '';
},
// 幫助方法
getElement : function(){
return this.element;
}
}
這是一個演示組合模式的工作方式的例子。每個類都很簡單,但由于有了這樣一種層次體系,我們就可以執(zhí)行一些復雜操作。GalleryImage類的構造函數(shù)會創(chuàng)建一個image元素。這個類定義中的其余部分由空的組合對象方法(因為這是葉結點)和GalleryItem要求的操作組成。現(xiàn)在我們可以使用這兩個類來管理圖片:
復制代碼 代碼如下:
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();
組合模式之利,使用組合模式,簡單的操作也能產(chǎn)生復雜的結果。不必編寫大師手工遍歷數(shù)組或其他數(shù)據(jù)結構的粘合代碼,只需對最頂層的對象執(zhí)行操作,主每一個子對象自己傳遞這個操作即可。這對于那些再三執(zhí)行的操作尤其有用。在組合模式中,各個對象之間的耦合非常松散。每當對頂層組合對象執(zhí)行一個操作時,實際上是在對整個結構進行嘗試優(yōu)先的搜索以查找節(jié)點。
組合模式之弊,由于對組合模式調(diào)用的任何操作都會被頗佳北至 它的所有子對象,如果這個層次體系很大的話,系統(tǒng)的性能將會受到影響。
您可能感興趣的文章:
- JavaScript適配器模式詳解
- javascript設計模式之Adapter模式【適配器模式】實現(xiàn)方法示例
- JavaScript設計模式之適配器模式介紹
- 深入理解JavaScript系列(39):設計模式之適配器模式詳解
- 詳解JavaScript實現(xiàn)設計模式中的適配器模式的方法
- javascript設計模式 – 適配器模式原理與應用實例分析
- JavaScript設計模式學習之適配器模式
- JavaScript組合模式學習要點
- 設計模式中的組合模式在JavaScript程序構建中的使用
- javascript設計模式 – 組合模式原理與應用實例分析
- JavaScript設計模式開發(fā)中組合模式的使用教程
- javascript適配器模式和組合模式原理與實現(xiàn)方法詳解
相關文章
JavaScript 繼承機制的實現(xiàn)(待續(xù))
JavaScript繼承機制的實現(xiàn),后期會有一些補充。2010-05-05