Skip to content

Latest commit

 

History

History
117 lines (100 loc) · 3.6 KB

File metadata and controls

117 lines (100 loc) · 3.6 KB

六. 组合模式

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

场景

我们平时开发过程中,一定会遇到这种情况:同时处理简单对象和由简单对象组成的复杂对象,这些简单对象和复杂对象会组合成树形结构,在客户端对其处理的时候要保持一致性。比如电商网站中的产品订单,每一张产品订单可能有多个子订单组合,比如操作系统的文件夹,每个文件夹有多个子文件夹或文件,我们作为用户对其进行复制,删除等操作时,不管是文件夹还是文件,对我们操作者来说是一样的。在这种场景下,就非常适合使用组合模式来实现。

组合模式主要有三个角色:

  1. 抽象组件(Component):抽象类,主要定义了参与组合的对象的公共接口
  2. 子对象(Leaf):组成组合对象的最基本对象
  3. 组合对象(Composite):由子对象组合起来的复杂对象

理解组合模式的关键是要理解组合模式对单个对象和组合对象使用的一致性,我们接下来说说组合模式的实现加深理解。

// 抽象一个虚拟父类
var News = function() {
  this.children = [];
  this.element = null;
};

News.prototype = {
  init: function() {
    throw new Error('请重写你的方法');
  },
  add: function() {
    throw new Error('请重写你的方法');
  },
  getElement: function() {
    throw new Error('请重写你的方法');
  }
};

function iniheritObject(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function inheritPrototype(subClass, superClass) {
  var p = iniheritObject(superClass.prototype);
  p.constructor = subClass;
  subClass.prototype = p;
}
//容器类
var Container = function(id, parent) {
  News.call(this);
  this.id = id;
  this.parent = parent;
  this.init();
};

//寄生式继承父类原型方法
inheritPrototype(Container, News);

Container.prototype.init = function() {
  this.element = document.createElement('ul');
  this.element.id = this.id;
  this.element.className = 'new-container';
};

Container.prototype.add = function(child) {
  this.children.push(child);
  this.element.appendChild(child.getElement());
  return this;
};

Container.prototype.getElement = function() {
  return this.element;
};

Container.prototype.show = function() {
  this.parent.appendChild(this.element);
};
//同样下一层极的行成员集合类以及后面新闻组合体类
var Item = function(classname) {
  News.call(this);
  this.classname = classname;
  this.init();
};
inheritPrototype(Item, News);
Item.prototype.init = function() {
  this.element = document.createElement('li');
  this.element.className = this.classname;
};
Item.prototype.add = function(child) {
  this.children.push(child);
  this.element.appendChild(child.getElement());
  return this;
};
Item.prototype.getElement = function() {
  return this.element;
};

var NewsGroup = function(className) {
  News.call(this);
  this.classname = classname || '';
  this.init();
};
inheritPrototype(NewsGroup, News);
NewsGroup.prototype.init = function() {
  this.element = document.createElement('div');
  this.element.className = this.classname;
};
NewsGroup.prototype.add = function(child) {
  this.children.push(child);
  this.element.appendChild(child.getElement());
  return this;
};
NewsGroup.prototype.getElement = function() {
  return this.element;
};

所以后面我们在使用的时候,创建新闻类,利用之前定义的组合元素去组合就可以了。