请仔细阅读下面代码,理解其中的设计理念。

组合模式
组合模式: 将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
实际场景
为了方便我们对多个文件的管理,我们引入了“文件夹-文件”的模式。将具有统一性质的文件放入一个文件夹中,将具有统一性质的文件夹再放入另一个文件夹中。可以对整个文件夹系统进行文件的搜索,也可以对某一个文件夹进行搜索。让文件管理变得简单。
而“文件夹-文件”这种结构就是典型 的组合模式。
组合模式的结构
- Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
- Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
- Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
组合模式的例子
Node枚举
/* node-type-enum.ts */
enum NodeTypeEnum {
ImageFile = 'image',
TextFile = 'text',
Folder = 'folder',
}
export {
NodeTypeEnum
}
Node抽象类
/* abstract-node.ts */
import { NodeTypeEnum } from './node-type-enum';
export abstract class AbstractNode {
protected name: string;
protected type: NodeTypeEnum;
protected children: AbstractNode[];
public abstract add(node: AbstractNode): AbstractNode;
public abstract getFileDeep(name: string): AbstractNode;
}
/* basic-file-folder.ts */
import { AbstractNode } from './abstract-node';
import { NodeTypeEnum } from './node-type-enum';
export abstract class BasicFile extends AbstractNode {
public add (file: BasicFile): BasicFile {
console.error('文件类型不支持添加');
return this;
}
public getFileDeep (name: string): BasicFile {
if (name === this.name) {
return this;
}
return null;
}
}
export abstract class BasicFolder extends AbstractNode {
protected constructor () {
super();
this.type = NodeTypeEnum.Folder;
this.children = [];
}
public add (file: AbstractNode): BasicFolder {
this.children.push(file);
return this;
}
public getFileDeep (name: string): AbstractNode {
if (this.name === name) {
return this;
}
for (let index = 0; index < this.children.length; index++) {
const node = this.children[index].getFileDeep(name);
if (node) {
return node;
}
}
return null;
}
}
文件类
/* files.ts */
import { BasicFile } from './basic-file-folder';
import { NodeTypeEnum } from './node-type-enum';
export class ImageFile extends BasicFile {
constructor (name: string) {
super();
this.name = name;
this.type = NodeTypeEnum.ImageFile;
}
}
export class TextFile extends BasicFile {
constructor (name: string) {
super();
this.name = name;
this.type = NodeTypeEnum.TextFile;
}
}
文件夹类
/* folder.ts */
import { BasicFolder } from './basic-file-folder';
export default class SystemFolder extends BasicFolder{
constructor(name){
super();
this.name = name;
}
}
客户端
/* client.ts */
import { ImageFile, TextFile } from './files';
import SystemFolder from './folder';
export default class Client {
public static initTree (): SystemFolder {
const folder1: SystemFolder = new SystemFolder('根文件夹');
const folder2: SystemFolder = new SystemFolder('图像文件夹');
const folder3: SystemFolder = new SystemFolder('文本文件夹');
const image1: ImageFile = new ImageFile('a.jpg');
const image2: ImageFile = new ImageFile('b.jpg');
const text1: TextFile = new TextFile('a.txt');
const text2: TextFile = new TextFile('b.txt');
folder2.add(image1).add(image2);
folder3.add(text1).add(text2);
folder1.add(folder2).add(folder3);
return folder1;
}
}
const tree = Client.initTree();
const aJpg = tree.getFileDeep('a.jpg');
console.log(aJpg);
组合模式的利弊
利:
弊:
组合模式掩盖了他所支持的每一种操作的代价。如果层次体系很大的话,系统的性能将会收到影响。
作者:我不叫奇奇
链接:https://www.jianshu.com/p/1f8c6ebaf6b6
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。