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

Posted yijingzheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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设计模式与开发时间》,曾探,中国工信出版集团.

 

以上是关于JavaScript设计模式总结-组合模式的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript---设计模式总结

JavaScript 创建对象 (工厂模式构造函数模式原型模式组合使用构造函数模式与原型模式)

Tailwind.css 体验总结

Tailwind.css 体验总结

Javascript 构造函数模式原型模式

Javascript设计模式总结之 -- 策略模式