JavaScript设计模式总结-组合模式

使用场景
1、对象存在整体-部分的结构,如树、数组等;
2、使用者希望对数据结构中的所有对象统一处理。
需要注意的是
1、组合模式所谓的结构并非“继承”,而是“包含”;
2、叶子节点、父节点、根节点的所有方法及属性要设计一致,对于某些不一致的地方可以通过抛出错误来提示;
3、若子节点映射多个父节点,则该模式不适用。

举例

以文件遍历、删除来说明,先定义一个文件夹类Folder
const Folder = function(name) {
  this.name = name;
  this.parent = null;
  this.files = [];
};
Folder.prototype.add = function(file) {
  file.parent = this;
  this.files.push(file);
};
Folder.prototype.scan = function() {
  console.log('扫描文件夹:', this.name);
  this.files.forEach(file => {
    file.scan();
  });
};
定义一个删除方法,这个方法是从节点的父节点中移除
Folder.prototype.remove = function() {
  if(!this.parent) { // 若为根节点,则不能移除
    return;
  };
  this.parent.files.forEach((file, index) => {
    if(file === this) {
      file.splice(index, 1);
    }
  });
};
文件类File同上
const File = function(name) {
  this.name = name;
  this.parent = null;
};
为了保证各层级节点的操作一致,需要定义add()方法,然而文件是不能执行这种操作的,因此在这里抛出错误来提示。
File.prototype.add = function() {
  throw new Error('不能在文件下添加');
};
File.prototype.scan = function() {
  console.log('扫描文件:', this.name);
};
File.prototype.remove = function() {
  if(!this.parent) {
    return;
  }
  this.parent.files.forEach((file, index) => {
    if (file === this) {
      file.splice(index, 1);
    }
  });
};
使用示例
const folder = new Folder('学习资料');
const folder1 = new Folder('Javascript');
const file1 = new Folder('深入浅出node.js');
folder1.add(new File('JavaScript设计模式与开发实践));
folder.add(folder1);
folder.add(file);
folder1.remove();
folder.scan();
 
 
思考
作为业务开发人员,其实这个模式基本用不上,如果服务端返回一个树状的菜单结构,难道还遍历一下数据,全部重新定义一遍节点?
显然不太合理,况且服务端返回的数据量可能产生变化,随着业务的逐步发展,数据变得越来越庞大,遍历所产生的开销还是不可忽视。
若自己做一个后台系统框架的通用的左侧列表功能,结合VueRouter的多层嵌套,可以试试用这种方式。
目前还是没有什么动力来写个框架。
 

参考文献:

[1] 《JavaScript设计模式与开发时间》,曾探,中国工信出版集团.

猜你喜欢

转载自www.cnblogs.com/yijingzheng/p/10231011.html