组合模式的透明性——不用顾忌树中组合对象和叶子对象的区别。
关键是同等对待组合对象和叶子对象,它们拥有相同的方法(相同的接口),这样就可以智能得处理组合对象还是叶子对象——使用抽象类。

抽象类在组合模式中的作用

相当于给组合对象和叶子对象提供相同接口

透明性带来的安全问题

解决方案:给叶子对象也增加add方法,调用时抛出一个异常来即使提醒客户。

例子:扫描文件夹

同等对待文件夹和文件

一些值得注意的地方

组合模式不是父子关系

只是组合对象把请求委托给它所包含的所有叶对象

对叶对象操作的一致性

只有一致的方式对待列表中的每个叶对象的时候,才适合使用组合模式
例如,只对jpg格式的文件扫描,就不适合(可以if条件判断,但是违背组合模式的初衷了)

双向映射关系

隶属于多个组合对象,不是单一的层次结构,就不能用组合模式,会收到两次或以上指令。

用职责链模式提高组合模式性能

职责链模式要手动设置链条。

引用父对象

当我们删除某个文件的时候,实际上是从这个文件所在的上层文件夹中删除改文件的。

  1. // 设置父对象
  2. Foler.prototype.add = function (file: File || Foler) {
  3. file.parent = this; // 文件或文件夹的父对象
  4. this.files.push(file);
  5. }
  6. Folder.prototype.remove = function (file) {
  7. if (!this.parent) {
  8. return;
  9. }
  10. for (var files = this.parent.files, len = files.length; len >=0; len--) {
  11. var file = files[l];
  12. if (file === this) {
  13. files.splice(len, 1);
  14. }
  15. }
  16. }

缺点

  1. 每个对象看起来差不多,运行的时候才显现出来,可能会使代码难以理解。
  2. 创建太多对象,降低性能。