摘要:組合設計模式組合模式,將對象組合成樹形結構以表示部分整體的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。
組合設計模式
組合模式,將對象組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。特點它使我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以像處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。它可以幫助開發者對多個具有相似功能對象進行分類, 提高規范化設計
有許多關于分級數據結構的例子,使得組合模式非常有用武之地。關于分級數據結構的一個普遍性的例子是你每次使用電腦時所遇到的:文件系統。文件系統由目錄和文件組成。每個目錄都可以裝內容。目錄的內容可以是文件,也可以是目錄。按照這種方式,計算機的文件系統就是以遞歸結構來組織的。如果你想要描述這樣的數據結構,那么你可以使用組合模式Composite。
涉及角色
在組合模式的層次體系中有兩種類型的對象: 葉對象和組合對象, 這是一種遞歸定義, 但者也是其有用的原因所在, 一個組合對象可以由其他組合對象和葉子對象組成, 但葉子對象不再包含子對象, 組合對象用于葉子節點的分類
這里借用 javascript設計模式 的圖來說明組合模式的設計
Interface 是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行為。聲明一個接口用于訪問和管理Component子部件。
Field 在組合中表示葉子結點對象,葉子結點沒有子結點, 可以設計成抽象類, 通過繼承設計出不同類別的葉子對象.
Composite 定義有子節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如增加(add)和刪除(remove)等。
接口
/* Interfaces. */ var Composite = new Interface("Composite", ["add", "remove", "getChild"]); var FormItem = new Interface("FormItem", ["save"]);
組合對象類
/* CompositeForm class. */ 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; };
葉子對象類
葉子對象可以是簡單的一個類, 也可以設計成抽象類構建不同類別的葉子, 在此采用抽象類設計不同類別的葉子
/* Field class, abstract. */ 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 類
/* InputField class. */ 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("div"); 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 類
/* TextareaField class. */ 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("div"); 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 類
/* SelectField class. */ 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("div"); 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; };使用
/* Usage. */ 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);
組合模式適合對大批對象進行操作, 且操作對象具有層次關系, 通過對對象的分類操作籍此弱化對象之間的耦合, 這種模式使得代碼模塊化程度更高, 層次更鮮明, 維護性較好
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107513.html
摘要:組合模式繼承結合了構造函數繼承時可以為每個屬性重新初始化,構造一個副本的優點,以及原型鏈繼承時一次定義處處共享的優點。但令我百思不得其解的是,從上面給出的例子來看,組合繼承并沒有調用兩次超類型構造函數。 最近在閱讀《js權威指南》的繼承這一章,對于組合模式和寄生組合模式的區別有點混淆,在多次重讀以及嘗試之后,得到一些心得。 組合模式繼承 結合了構造函數繼承時可以為每個屬性重新初始化,構...
摘要:文章系列設計模式單例模式設計模式策略模式設計模式代理模式設計模式迭代器模式設計模式發布訂閱模式設計模式命令模式概念組合模式就是用小的子對象來構建更大的對象,而這些小的子對象本身也許是由更小的孫對象構成的。 前言 本系列文章主要根據《JavaScript設計模式與開發實踐》整理而來,其中會加入了一些自己的思考。希望對大家有所幫助。 文章系列 js設計模式--單例模式 js設計模式--策略...
摘要:實現思路使用原型鏈實現對原型方法和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承。繼承屬性繼承方法以上代碼,構造函數定義了兩個屬性和。 JS面向對象的程序設計之繼承的實現-組合繼承 前言:最近在細讀Javascript高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯誤,會非常感謝您的指出。文中絕大部分內容引用自《Java...
摘要:對象經典對象創建與繼承模式組合模式創建對象中創建一個對象的方式多種多樣,每種方式都有自己缺點或者優點,具體的可以參考而組合使用構造函數模式和原型模式來創建自定義類型算是最常見的方式了。 title: JS對象(3)經典對象創建與繼承模式 date: 2016-09-28 tags: JavaScript 0x01 組合模式創建對象 JS 中創建一個對象的方式多種多樣,...
摘要:單向數據流應用的核心設計模式,數據流向自頂向下我也是性子急的人,按照技術界的慣例,在學習一個技術前,首先得說一句。然而的單向數據流的設計讓前端定位變得簡單,頁面的和數據的對應是唯一的我們可以通過定位數據變化就可以定位頁面展現問題。 書籍完整目錄 1.1 React 介紹 showImg(https://segmentfault.com/img/bVvJgS); 1.1.1 React ...
閱讀 3028·2021-11-12 10:36
閱讀 4762·2021-09-22 10:57
閱讀 1579·2021-09-22 10:53
閱讀 2665·2019-08-30 15:55
閱讀 3501·2019-08-29 17:00
閱讀 3357·2019-08-29 16:36
閱讀 2474·2019-08-29 13:46
閱讀 1354·2019-08-26 11:45