资讯专栏INFORMATION COLUMN

js设计模式 --- 组合设计模式

ninefive / 1323人阅读

摘要:组合设计模式组合模式,将对象组合成树形结构以表示部分整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合设计模式
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。它可以帮助开发者对多个具有相似功能对象进行分类, 提高规范化设计

有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式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);
组合模式适合对大批对象进行操作, 且操作对象具有层次关系, 通过对对象的分类操作籍此弱化对象之间的耦合, 这种模式使得代码模块化程度更高, 层次更鲜明, 维护性较好

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107513.html

相关文章

  • js组合模式和寄生组合模式的区别研究

    摘要:组合模式继承结合了构造函数继承时可以为每个属性重新初始化,构造一个副本的优点,以及原型链继承时一次定义处处共享的优点。但令我百思不得其解的是,从上面给出的例子来看,组合继承并没有调用两次超类型构造函数。 最近在阅读《js权威指南》的继承这一章,对于组合模式和寄生组合模式的区别有点混淆,在多次重读以及尝试之后,得到一些心得。 组合模式继承 结合了构造函数继承时可以为每个属性重新初始化,构...

    tolerious 评论0 收藏0
  • js设计模式--组合模式

    摘要:文章系列设计模式单例模式设计模式策略模式设计模式代理模式设计模式迭代器模式设计模式发布订阅模式设计模式命令模式概念组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的孙对象构成的。 前言 本系列文章主要根据《JavaScript设计模式与开发实践》整理而来,其中会加入了一些自己的思考。希望对大家有所帮助。 文章系列 js设计模式--单例模式 js设计模式--策略...

    blankyao 评论0 收藏0
  • JS面向对象的程序设计之继承的实现-组合继承

    摘要:实现思路使用原型链实现对原型方法和方法的继承,而通过借用构造函数来实现对实例属性的继承。继承属性继承方法以上代码,构造函数定义了两个属性和。 JS面向对象的程序设计之继承的实现-组合继承 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以用自己所理解的,尝试解读下。如有纰漏或错误,会非常感谢您的指出。文中绝大部分内容引用自《Java...

    antz 评论0 收藏0
  • JS对象(3)经典对象创建与继承模式

    摘要:对象经典对象创建与继承模式组合模式创建对象中创建一个对象的方式多种多样,每种方式都有自己缺点或者优点,具体的可以参考而组合使用构造函数模式和原型模式来创建自定义类型算是最常见的方式了。 title: JS对象(3)经典对象创建与继承模式 date: 2016-09-28 tags: JavaScript 0x01 组合模式创建对象 JS 中创建一个对象的方式多种多样,...

    hellowoody 评论0 收藏0
  • 精益 React 学习指南 (Lean React)- 1.1 React 介绍

    摘要:单向数据流应用的核心设计模式,数据流向自顶向下我也是性子急的人,按照技术界的惯例,在学习一个技术前,首先得说一句。然而的单向数据流的设计让前端定位变得简单,页面的和数据的对应是唯一的我们可以通过定位数据变化就可以定位页面展现问题。 书籍完整目录 1.1 React 介绍 showImg(https://segmentfault.com/img/bVvJgS); 1.1.1 React ...

    lsxiao 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<