定义
将对象组合成树形结构以表示“部分——整体”的层次结构
菜单有子菜单,子菜单还有子菜单,可以一直递归下去
使设计变得抽象
使用场景
- 处理树形结构
- 忽略组合与单个对象的差异
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
@AllArgsConstructor
public class Course implements CatalogComponent {
private String courseName;
private Double coursePrice;
@Override
public String getName() {
return this.courseName;
}
@Override
public Double getPrice() {
return this.coursePrice;
}
@Override
public void print() {
System.out.println(this);
}
}
目录类
这里使用Data注解是为了好转化成json,也好打印list的结构
@Data
public class CourseCatalog implements CatalogComponent {
private List<CatalogComponent> items = new ArrayList<>();
private String name;
public CourseCatalog(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
@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);
}
}
测试方法
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=主目录
)
小结
组合模式,将多个类实现同一接口或继承同一父类