JavaScript设计模式(七):组合模式

128 阅读1分钟

定义

组合模式:使用小的子对象来构建更大的对象,将对象组合成树形结构以表示“部分-整体”的层次结构。

这个像书的目录了。

实现

const Folder = function (name) {
  this.name = name
  this.files = []
}
Folder.prototype.add = function (file) {
  console.log('开始扫描文件夹:', this.name)
  this.files.push(file)
}
Folder.prototype.scan = function (file) {
  for (let file of this.files) {
    file.scan()
  }
}

const File = function (name) {
  this.name = name
}
File.prototype.add = function (file) {
  throw new Error('文件下面不能再添加文件')
}
File.prototype.scan = function (file) {
  console.log(`开始扫描文件:${this.name}`)
}

let movieFolder = new Folder('电影文件夹')
let musicFolder = new Folder('音乐文件夹')

let file1 = new File('钢铁侠.mp4')
let file2 = new File('再谈记忆.mp3')
movieFolder.add(file1)
movieFolder.scan()
musicFolder.add(file2)
musicFolder.scan()

注意点:

  • 组合模式不是父子关系

    组合模式虽然是树形结构,但是上下级之间并不是父子关系。
  • 对叶对象操作一致性

    组合模式除了组合对象和叶对象拥有相同的接口之外,还有就是一组叶对象的操作也须保持一致性。
  • 双向映射关系

    叶对象与数对象之间是严格的层次结构,不能存在一个叶对象对应多个树对象。
  • 用职责链模式提供组合模式性能

    在组合模式中,如果树的结构过于复杂,遍历树的过程中,会消耗很多性能。这时,就可以使用职责链模式,手动设置树对象与叶对象之间的关系,来提高查找的性能。

总结

当我们想表示层次结构时,用组合模式是很合适的。但是吧,它会带来很多相似的对象,这会使代码难以理解,同时,如果创建对象过多的话,会额外增加内存负担。