定义
将对象组合成树形结构以表示“部分——整体”的层次结构
菜单有子菜单,子菜单还有子菜单,可以一直递归下去
使设计变得抽象

使用场景
- 处理树形结构
- 忽略组合与单个对象的差异
Demo设计
假设要展示课程目录,子目录可能还会有子目录,适合使用组合模式
组件接口
定义一个接口目录组件接口,不管是实体类还是目录类都继承此接口都可以添加到树形结构中
public interface CatalogComponent {default void add(CatalogComponent catalogComponent) {throw new UnsupportedOperationException("不支持添加操作");}default void remove(CatalogComponent catalogComponent) {throw new UnsupportedOperationException("不支持删除操作");}default String getName() {throw new UnsupportedOperationException("不支持获取名称操作");}default Double getPrice() {throw new UnsupportedOperationException("不支持获取价格操作");}default void print() {throw new UnsupportedOperationException("不支持打印操作");}}
抛异常的话转换成json会出错,还是改成空方法吧
public interface CatalogComponent {default void add(CatalogComponent catalogComponent) {}default void remove(CatalogComponent catalogComponent) {}default String getName() {return null;}default Double getPrice() {return null;}default void print() {}}
实体类
课程类
@Data@NoArgsConstructor@AllArgsConstructorpublic class Course implements CatalogComponent {private String courseName;private Double coursePrice;@Overridepublic String getName() {return this.courseName;}@Overridepublic Double getPrice() {return this.coursePrice;}@Overridepublic void print() {System.out.println(this);}}
目录类
这里使用Data注解是为了好转化成json,也好打印list的结构
@Datapublic class CourseCatalog implements CatalogComponent {private List<CatalogComponent> items = new ArrayList<>();private String name;public CourseCatalog(String name) {this.name = name;}@Overridepublic String getName() {return this.name;}@Overridepublic void add(CatalogComponent catalogComponent) {items.add(catalogComponent);}@Overridepublic void remove(CatalogComponent catalogComponent) {items.remove(catalogComponent);}@Overridepublic void print() {System.out.println(this);}}
测试方法
public static void main(String[] args) {//操作系统课程目录CatalogComponent systemCatalog = new CourseCatalog("操作系统");//操作系统课程CatalogComponent linuxCourse = new Course("Linux", 11);CatalogComponent windowsCourse = new Course("Windows", 11);systemCatalog.add(linuxCourse);systemCatalog.add(windowsCourse);//java课程目录CatalogComponent javaCourseCatalog = new CourseCatalog("java课程目录");//java课程CatalogComponent javaSeCourse = new Course("JavaSE", 11);//项目课程目录CatalogComponent mallCatalog = new CourseCatalog("项目");CatalogComponent mallCourse1 = new Course("电商项目1期", 77);CatalogComponent mallCourse2 = new Course("电商项目2期", 77);mallCatalog.add(mallCourse1);mallCatalog.add(mallCourse2);javaCourseCatalog.add(javaSeCourse);javaCourseCatalog.add(mallCatalog);CatalogComponent mainCatalog = new CourseCatalog("主目录");mainCatalog.add(systemCatalog);mainCatalog.add(javaCourseCatalog);mainCatalog.print();}
将打印出来的对象格式化一下就是这样,实现树形结构,子菜单的子菜单
可以将此对象转换为json传给前端用于显示
CourseCatalog(items=[CourseCatalog(items=[Course(courseName=Linux, coursePrice=11.0),Course(courseName=Windows, coursePrice=11.0)], name=操作系统),CourseCatalog(items=[Course(courseName=JavaSE, coursePrice=11.0),CourseCatalog(items=[Course(courseName=电商项目1期, coursePrice=77.0),Course(courseName=电商项目2期, coursePrice=77.0)], name=项目)], name=java课程目录)],name=主目录)
小结
组合模式,将多个类实现同一接口或继承同一父类
