组合模式
组合模式:
掌握组合模式的 透明写法 和 安全写法
一个国家会设立很多机构,如三省六部,这些机构下又又很多小的组织。他们共同管理这个国家
一个公司下面有很多部门,每个部门下面又有很多小组。这就是组合模式
组合模式:Composite Pattern
又叫 整体-部分模式,整体和个体共性,全部放到一个抽象中统一处理
宗旨:通过将单个对象(叶子节点)和 组合对象(树枝节点)用相同的接口进行表示,使得客户对 单个对象 和 组合对象 的使用具有一致性
属于结构型模式
组合关系 和 聚合关系 的区别:
组合关系:在古代,皇帝有三宫六院,贵妃很多,但是每个妃嫔只属于皇帝(具有相同的生命周期)
聚合关系:一个老师有很多学生,但是每一个学生又属于多个老师(具有不同的生命周期)
组合模式一般用来描述 整理 和 部分 的关系,他将对象组织到 树形结构 中,最顶层的节点为根节点,根节点 下面可以包含 树枝节点 和 叶子节点,树枝节点 下面又可以包含 树枝节点 和叶子节点
根节点 和 树枝节点 本质上是同一种数据类型,可以作为容器使用
叶子节点 和 树枝节点 再语义上不属于同一种类型,但是在组合模式中,会把 叶子节点 和 树枝节点 认为是同一种数据类型(用同一接口定义),让他们具备一致行为。
所以,在组合模式中,整个树形结构中的对象都是同一种类型,带来的好处就是 客户端无需辨别 叶子节点 还是 树枝节点,而是可以直接进行操作,给客户使用带来极大的便利
组合模式包含3个角色:
抽象根节点(Component): 定义系统各层次对象的 共有方法 和 共有属性,可以预先定义默认行为和属性
树枝节点(Composite): 定义树枝节点的行为,存储子节点,组合树枝节点 和 叶子节点 形成一个树形结构
叶子节点(Leaf): 叶子节点对象,其再无分支,是系统层次遍历的最小单位
组合模式 在代码实现上,有两种不同方式,透明组合模式 和 安全组合模式
应用场景:
希望客户端可以忽略 组合对象 和 单个对象的差异时
对象层次具备 整体 和 部分,成树形结构
生活中那个的组合模式:
树形菜单、操作系统目录结构、公司组织架构等
透明写法和安全写法有啥区别?
透明:所有都写在抽象中
安全:只有具有共性的内容写在抽象中
透明组合模式的写法:
透明组合模式 是把所有公共方法都定义在 Component 中,这样做的好处是 客户端无需分辨是 叶子节点(Leaf)还是 树枝节点(Composite), 他们具备完全一致的接口。
vip.pattern.composite.general.transparent
业务实例:
以课程学习为例,设计一个课程的关系结构
比如有 Java入门课程、人工只能课程、Java设计模式、源码分析等,而 Java设计模式、源码分析 又属于 Java架构师系列课程包,每个课程的定价都不一样。
但是,这些课程不论怎么组合,都有一些共性,而且是整体与部分的关系,可以用组合模式来设计。
创建顶层的抽象组件 CourseComponent 类, 把所有可能用到的方法都定义到抽象类中
创建课程 Course 类,定义课程基础信息
创建课程包 CoursePackage 类,具体组合方法的实现
vip.pattern.composite.demo.transparent
透明组合模式的缺点是:叶子节点(Leaf)会继承得到一些它所不需要的方法,违背了接口隔离原则
安全组合模式的写法:
安全组合模式 是只规定系统各个层次的最基础的一致行为,而把组合(树叶节点)本身的方法(管理子类对象的添加、删除)放到自身当中。
vip.pattern.composite.general.safe
业务实例:
电脑的文件系统,典型的树形结构,目录包含文件夹和文件,文件夹里又可以包含文件夹和文件
创建顶层的抽象组件 Directory 类,
创建 File 类,
创建 Folder 类,
vip.pattern.composite.demo.safe
安全组合模式的好处是:接口定义职责清晰,符合 单例职责原则 和 接口隔离原则
缺点是:客户需要区分数据类型,树枝节点(Composite) 和 叶子节点(Leaf),这样才能正确处理各个层次的操作,客户端无法依赖抽象,违背依赖倒置原则
组合对象 和 被组合对象 都应该又统一的接口实现 或者 统一的抽象父类。
组合模式一定是树形接口吗?
不一定,不管你是整体还是个体,都要想办法用同一种方法来操作
组合模式至少有一个共性
源码中的体现:
HashMap 的 putAll() 方法
putAll() 方法传入的是 Map 对象,Map 就是一个抽象构件,而 HashMap 是一个中间构件,HashMap 中的 Node 节点就是 叶子节点
ArrayList 的 addAll() 方法
MyBatis 解析各种 Mapping 文件中的 SQL , 设计了一个非常关键的类 SqlNode,xml 中的每个 Node 都会解析为一个 SqlNode 对象,最后把所有的 SqlNode 拼装到一起就成了一条完整的Sql 语句
组合模式的优缺点:
优点:
清楚的定义分层次的复杂对象,表示对象的全部或部分层次
让客户端忽略层次的差异,方便对整个层次结构进行控制
简化客户端代码
符合开闭原则
缺点:
限制类型时会比较复杂
使设计变得更加抽象
作业:
2、请用组合模式实现一个无限级扩展的树(提示,可以引入xpath)。
id parentId xpath level
1 1 /1 1
2 1 /1/2 2
3 2 /1/2/3 3