该项目源码地址:https://github.com/ggb2312/JavaNotes/tree/master/design-pattern (设计模式相关代码与笔记)
1. 定义
将对象组合成树形结构以表示“部分一整体”的层次结构
2. 适用情况
- 希望客户端可以忽略组合对象与单个对象的差异时
- 处理一个树形结构时
3. 类图以及角色
- Component是对象声明接口,在适当情况下,实现所有类共有接口的默认行为。
- Leaf是叶子节点对象,其没有子节点。
- Composite是树枝节点对象,用来存储部件,组合树枝节点和叶子节点形成一个树形结构。
4. 相关设计模式
组合模式和访问者模式
- 可以使用访问者模式访问组合模式的递归结构。
5. 模式实例
背景:慕课网要对课程进行划分目录结构
Component 有一个课程的抽象类:
public abstract class CatalogComponent {
public void add(CatalogComponent catalogComponent) {
throw new UnsupportedOperationException("不支持添加操作");
}
public void remove(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("不支持打印操作");
}
}
Leaf 课程类:
public class Course extends CatalogComponent{
private String name;
private double price;
public Course(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("Course Name :"+name+" price"+price);
}
}
Composite 目录类:
public class CourseCatalog extends CatalogComponent {
private List<CatalogComponent> items = new ArrayList<>();
private String name;
private Integer level;
public CourseCatalog(String name, Integer level) {
this.name = name;
this.level = level;
}
@Override
public void add(CatalogComponent catalogComponent) {
items.add(catalogComponent);
}
@Override
public void remove(CatalogComponent catalogComponent) {
items.remove(catalogComponent);
}
@Override
public void print() {
System.out.println(this.name);
for (CatalogComponent catalogComponent : items) {
if (level != null) {
for (int i=0;i<level;i++){
System.out.print("-");
}
}
catalogComponent.print();
}
}
}
此时的类图:
测试类:
public class Test {
public static void main(String[] args) {
CatalogComponent linuxCourse = new Course("Linux课程", 11);
CatalogComponent windowsCourse = new Course("windows课程", 11);
CatalogComponent javaCourseCatalog = new CourseCatalog("Java课程目录",2);
CatalogComponent mmallCatalog1 = new Course("Java电商一期", 55);
CatalogComponent mmallCatalog2 = new Course("Java电商二期", 66);
CatalogComponent designPattern = new Course("Java设计模式", 77);
javaCourseCatalog.add(mmallCatalog1);
javaCourseCatalog.add(mmallCatalog2);
javaCourseCatalog.add(designPattern);
CatalogComponent imoocMainCourseCatalog = new CourseCatalog("网站课程主目录",1);
imoocMainCourseCatalog.add(linuxCourse);
imoocMainCourseCatalog.add(windowsCourse);
imoocMainCourseCatalog.add(javaCourseCatalog);
imoocMainCourseCatalog.print();
}
}
测试结果:
6. 优缺点
优点:
- 清楚地定义分层次的复杂对象,表示对象的全部或部分层次
- 让客户端忽略了层次的差异,方便对整个层次结构进行控制
- 简化客户端代码
- 符合开闭原则
缺点:
- 限制类型时会较为复杂
- 使设计变得更加抽象
7. 扩展-JDK1.7以及框架源码中的组合模式
7.1 jdk
- java.awt.Container、Component
- java.util.HashMap、
- java.util.ArrayList、List、Collection
7.2 Mybatis
org.apache.ibatis.scripting.xmltags.SqlNode
MixedSqlNode相当于CourseCatalog课程目录