一、组合模式的定义与类型
1、定义
- 将对象组合成树形结构以表示“部分-整体”的层次结构
- 组合模式使客户端对单个对象和组合对象保持一致的方式处理
2、类型
- 结构型
二、组合模式的适用场景
- 希望客户端可以忽略组合对象与单个对象的差异时
- 处理一个树形结构时
三、组合模式的优点
- 清楚的定义分层次的复杂对象,表示对象的全部或部分层次
- 让客户端忽略了层次的差异,方便对整个层次结构进行控制
- 简化客户端代码
- 符合开闭原则
四、组合模式的缺点
- 限制类型时会较为复杂
- 使设计变得更加抽象
五、组合模式相关的设计模式
- 组合模式和访问者模式
六、组合模式示例
示例描述:以课程和课程组成的课程目录为例。
1、创建一个抽象的目录组件类:
package com.rf.designPatterns.structural.composite;
/**
* @description: 创建一个抽象的目录组件类
* @author: xiaozhi
* @create: 2020-07-09 10:39
*/
public abstract class CatalogComponent {
public void insert(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持添加目录操作");
}
public void delete(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持删除目录操作");
}
public String getName(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持获目录名称操作");
}
public Double getPrice(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持目录价格操作");
}
public void print(){
throw new UnsupportedOperationException("不支持打印目录操作");
}
}
2、创建一个课程类
package com.rf.designPatterns.structural.composite;
/**
* @description: 创建一个课程类
* @author: xiaozhi
* @create: 2020-07-09 10:45
*/
public class Cource extends CatalogComponent{
private String name; //课程名称
private Double price; //课程价格
public Cource(String name, Double price) {
this.name = name;
this.price = price;
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public Double getPrice(CatalogComponent catalogComponent) {
return this.price;
}
@Override
public void print() {
System.out.println("课程的名称:"+name+",价格:"+price);
}
}
3、创建一个课程目录类
package com.rf.designPatterns.structural.composite;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 创建一个课程目录类
* @author: xiaozhi
* @create: 2020-07-09 10:59
*/
public class CourseCatalog extends CatalogComponent{
private List<CatalogComponent> list=new ArrayList<CatalogComponent>();
private String name; //课程目录名称
private Integer level;课程目录等级
public CourseCatalog(String name,Integer level) {
this.name = name;
this.level=level;
}
@Override
public void insert(CatalogComponent catalogComponent) {
list.add(catalogComponent);
}
@Override
public void delete(CatalogComponent catalogComponent) {
list.remove(catalogComponent);
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public void print() {
System.out.println(this.name);
for(CatalogComponent item :list){
if(this.level!=null){
for(int i=0;i<this.level;i++){
System.out.print(" ");
}
item.print();
}
}
}
}
4、创建测试类
package com.rf.designPatterns.structural.composite;
/**
* @description: 测试类 组合模式
* @author: xiaozhi
* @create: 2020-07-09 11:20
*/
public class Test {
public static void main(String[] args) {
/***
* @Description: 创建一级课程主目录和一级课程
* @Param: [args]
* @Author: xz
* @return: void
* @Date: 2020/7/9 15:59
*/
//创建一级课程主目录
CourseCatalog mainCourseCatalog=new CourseCatalog("课程主目录.......",1);
//创建一级课程
CatalogComponent linuxCource = new Cource("linux课程", 70.00);
CatalogComponent jvmCource = new Cource("JVM课程", 80.00);
//把所有一级课程添加到一级课程主目录
mainCourseCatalog.insert(linuxCource);
mainCourseCatalog.insert(jvmCource);
/***
* @Description: 创建二级课程主目录和二级课程
* @Param: [args]
* @Author: xz
* @return: void
* @Date: 2020/7/9 15:59
*/
//创建二级课程目录
CourseCatalog javaCourseCatalog=new CourseCatalog("java课程目录.......",2);
//创建二级课程
CatalogComponent javaDesginCource = new Cource("java设计模式", 65.00);
CatalogComponent javaThreadCource = new Cource("java多线程", 75.00);
CatalogComponent javaConcurrentCource = new Cource("java并发编程", 85.00);
//把二级课程添加到二级课程目录
javaCourseCatalog.insert(javaDesginCource);
javaCourseCatalog.insert(javaThreadCource);
javaCourseCatalog.insert(javaConcurrentCource);
//把二级课程目录添加到一级课程主目录
mainCourseCatalog.insert(javaCourseCatalog);
mainCourseCatalog.print();
}
}
5、输出结果如下:
6、类图如下: