宁可枝头抱香死,何曾吹落北风中。这篇文章主要讲述分分钟理解组合模式相关的知识,希望能为你提供帮助。
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
树对象和叶对象接口统一,树对象增加一个缓存数组,存储叶对象。执行树对象方法时,将请求传递给其下叶对象执行。
// 树对象 - 文件目录
class CFolder
constructor(name)
this.name = name;
this.files = [];
add(file)
this.files.push(file);
scan()
for (let file of this.files)
file.scan();
// 叶对象 - 文件
class CFile
constructor(name)
this.name = name;
add(file)
throw new Error(文件下面不能再添加文件);
scan()
console.log(`开始扫描文件:$this.name`);
let mediaFolder = new CFolder(娱乐);
let movieFolder = new CFolder(电影);
let musicFolder = new CFolder(音乐);
let file1 = new CFile(钢铁侠.mp4);
let file2 = new CFile(再谈记忆.mp3);
movieFolder.add(file1);
musicFolder.add(file2);
mediaFolder.add(movieFolder);
mediaFolder.add(musicFolder);
mediaFolder.scan();
/* 输出:
开始扫描文件:钢铁侠.mp4
开始扫描文件:再谈记忆.mp3
*/
?
?CFolder?
?与
??CFile?
?
接口保持一致。执行
??scan()?
?
时,若发现是树对象,则继续遍历其下的叶对象,执行
??scan()?
?。javascript 不同于其它静态编程语言,实现组合模式的难点是保持树对象与叶对象之间接口保持统一,可借助 TypeScript 定制接口规范,实现类型约束。
// 定义接口规范
interface Compose
name: string,
add(file: CFile): void,
scan(): void
// 树对象 - 文件目录
class CFolder implements Compose
fileList = [];
name: string;
constructor(name: string)
this.name = name;
add(file: CFile)
this.fileList.push(file);
scan()
for (let file of this.fileList)
file.scan();
// 叶对象 - 文件
class CFile implements Compose
name: string;
constructor(name: string)
this.name = name;
add(file: CFile)
throw new Error(文件下面不能再添加文件);
scan()
console.log(`开始扫描:$this.name`)
let mediaFolder = new CFolder(娱乐);
let movieFolder = new CFolder(电影);
let musicFolder = new CFolder(音乐);
let file1 = new CFile(钢铁侠.mp4);
let file2 = new CFile(再谈记忆.mp3);
movieFolder.add(file1);
musicFolder.add(file2);
mediaFolder.add(movieFolder);
mediaFolder.add(musicFolder);
mediaFolder.scan();
/* 输出:
开始扫描文件:钢铁侠.mp4
开始扫描文件:再谈记忆.mp3
*/
需要注意的是:
- 组合不是继承,树叶对象并不是父子对象
- 叶对象操作保持一致性
- 叶对象实现冒泡传递
- 不只是简单的子集遍历
- 优化处理递归或分级数据结构(文件系统 - 目录文件管理);
- 与其它设计模式联用,如与命令模式联用实现 “宏命令”。
【分分钟理解组合模式】它的缺点:树叶对象接口一致,无法区分,只有在运行时方可辨别;包裹对象创建太多,额外增加内存负担。
推荐阅读
- 华为ENSP做热备份路由选择
- 阿里巴巴笔试题 -- 动态规划实现两个字符串的最短编辑记录
- 微信小游戏开发实战11:使用本地缓存
- spring cloud alibaba gatewaynacos503错误代码
- python入门
- #yyds干货盘点#vue中mockjs的使用
- #yyds干货盘点# Java 内存分析之堆内存和MetaSpace内存
- 想从单体架构演进到分布式架构,SBA 会是一个不错的选择
- OpenStack Train(系统环境实施准备)