它使我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以像處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。它可以幫助開發者對多個具有相似功能對象進行分類, 提高規范化設計
有許多關于分級數據結構的例子,使得組合模式非常有用武之地。關于分級數據結構的一個普遍性的例子是你每次使用電腦時所遇到的:文件系統。文件系統由目錄和文件組成。每個目錄都可以裝內容。目錄的內容可以是文件,也可以是目錄。按照這種方式,計算機的文件系統就是以遞歸結構來組織的。如果你想要描述這樣的數據結構,那么你可以使用組合模式Composite。
涉及角色
特點
在組合模式的層次體系中有兩種類型的對象: 葉對象和組合對象, 這是一種遞歸定義, 但者也是其有用的原因所在, 一個組合對象可以由其他組合對象和葉子對象組成, 但葉子對象不再包含子對象, 組合對象用于葉子節點的分類
設計
這里借用 javascript設計模式 的圖來說明組合模式的設計
Interface 是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行為。聲明一個接口用于訪問和管理Component子部件。
Field 在組合中表示葉子結點對象,葉子結點沒有子結點, 可以設計成抽象類, 通過繼承設計出不同類別的葉子對象.
Composite 定義有子節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如增加(add)和刪除(remove)等。
接口
var Composite = new Interface('Composite', ['add', 'remove', 'getChild']); var FormItem = new Interface('FormItem', ['save']);
組合對象類
var CompositeForm = function(id, method, action) { // implements Composite, FormItem this.formComponents = []; this.element = document.createElement('form'); this.element.id = id; this.element.method = method || 'POST'; this.element.action = action || '#'; }; CompositeForm.prototype.add = function(child) { Interface.ensureImplements(child, Composite, FormItem); this.formComponents.push(child); this.element.appendChild(child.getElement()); }; CompositeForm.prototype.remove = function(child) { for(var i = 0, len = this.formComponents.length; i < len; i++) { if(this.formComponents[i] === child) { this.formComponents.splice(i, 1); // Remove one element from the array at // position i. break; } } }; CompositeForm.prototype.getChild = function(i) { return this.formComponents[i]; }; CompositeForm.prototype.save = function() { for(var i = 0, len = this.formComponents.length; i < len; i++) { this.formComponents[i].save(); } }; CompositeForm.prototype.getElement = function() { return this.element; };
葉子對象類
葉子對象可以是簡單的一個類, 也可以設計成抽象類構建不同類別的葉子, 在此采用抽象類設計不同類別的葉子var Field = function(id) { // implements Composite, FormItem this.id = id; this.element; }; Field.prototype.add = function() {}; Field.prototype.remove = function() {}; Field.prototype.getChild = function() {}; Field.prototype.save = function() { setcookie(this.id, this.getValue); }; Field.prototype.getElement = function() { return this.element; }; Field.prototype.getValue = function() { throw new Error('Unsupported operation on the class Field.'); };
InputField 類
var InputField = function(id, label) { // implements Composite, FormItem Field.call(this, id); this.input = document.createElement('input'); this.input.id = id; this.label = document.createElement('label'); var labelTextNode = document.createTextNode(label); this.label.appendChild(labelTextNode); this.element = document.createElement('p'); this.element.className = 'input-field'; this.element.appendChild(this.label); this.element.appendChild(this.input); }; extend(InputField, Field); // Inherit from Field. InputField.prototype.getValue = function() { return this.input.value; };
textareaField 類
var textareaField = function(id, label) { // implements Composite, FormItem Field.call(this, id); this.textarea = document.createElement('textarea'); this.textarea.id = id; this.label = document.createElement('label'); var labelTextNode = document.createTextNode(label); this.label.appendChild(labelTextNode); this.element = document.createElement('p'); this.element.className = 'input-field'; this.element.appendChild(this.label); this.element.appendChild(this.textarea); }; extend(textareaField, Field); // Inherit from Field. textareaField.prototype.getValue = function() { return this.textarea.value; };
SelectField 類
var SelectField = function(id, label) { // implements Composite, FormItem Field.call(this, id); this.select = document.createElement('select'); this.select.id = id; this.label = document.createElement('label'); var labelTextNode = document.createTextNode(label); this.label.appendChild(labelTextNode); this.element = document.createElement('p'); this.element.className = 'input-field'; this.element.appendChild(this.label); this.element.appendChild(this.select); }; extend(SelectField, Field); // Inherit from Field. SelectField.prototype.getValue = function() { return this.select.options[this.select.selectedIndex].value; };
使用
var contactForm = new CompositeForm('contact-form', 'POST', 'contact.php'); contactForm.add(new InputField('first-name', 'First Name')); contactForm.add(new InputField('last-name', 'Last Name')); contactForm.add(new InputField('address', 'Address')); contactForm.add(new InputField('city', 'City')); contactForm.add(new SelectField('state', 'State', stateArray)); // var stateArray =[{'al', 'Alabama'}, ...] contactForm.add(new InputField('zip', 'Zip')); contactForm.add(new textareaField('comments', 'Comments')); addEvent(window, 'unload', contactForm.save);
組合模式適合對大批對象進行操作, 且操作對象具有層次關系, 通過對對象的分類操作籍此弱化對象之間的耦合, 這種模式使得代碼模塊化程度更高, 層次更鮮明, 維護性較好
相關推薦:
js橋接設計模式詳解
Node.js中通用基礎設計模式實例分析
js代理設計模式詳解
以上就是js組合設計模式詳解的詳細內容,更多請關注php中文網其它相關文章!