学习路径:https://coding.imooc.com/class/270.html
- 应用场景
1.处理树形结构
2.简化客户端的操作
/**
* 将目录和目录下的课程抽象成目录组件,方便地组合、删除、打印
*
* @param args
*/
public static void main(String[] args) {
// 创建目录
CatalogComponent mainCatalog = new CourseCatalog("主目录",1);
CatalogComponent pythonCatalog = new CourseCatalog("python课程", 2);
CatalogComponent javaCatalog = new CourseCatalog("java web课程",2);
// 创建课程
CatalogComponent designCourse = new Course("java设计模式课程",15);
CatalogComponent mysqlCourse = new Course("mybatis课程",15);
CatalogComponent spiderCourse = new Course("python爬虫课程",125);
// 二级目录目录装载课程
pythonCatalog.add(spiderCourse);
javaCatalog.add(designCourse);
javaCatalog.add(mysqlCourse);
// 一级目录装载课程
mainCatalog.add(pythonCatalog);
mainCatalog.add(javaCatalog);
// 打印主目录下的所有课程
mainCatalog.print();
}
// 增加目录
mainCatalog.add(new CourseCatalog("C++课程",2));
// 该目录下可以有任意的课程或者目录,他们都是组件
- 实现
继承同一个父类或者实现同一个接口,本质是多态的实现。
/**
* 一个公共的抽象类,提供课程、目录的默认方法
*/
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("不支持打印操作");
}
}
public class Course extends CatalogComponent {
private String name;
private double price;
// 外部New出对象后要指定相关属性,不同的CatalogComponent可能拥有不同的属性,属性的不同,可以对元素添加不同的行为
public Course(String name, double price) {
this.name = name;
this.price = price;
}
// 省略其他方法
}
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;
}
// 省略其他方法
}
/**
* 目录元素的print方法
*/
@Override
public void print(){
System.out.println("目录名称:" + this.getName(this));
if (this.level != null) {
for (CatalogComponent element : items) {
for (int i = 0; i < this.level; i++) {
System.out.print(" ");
}
// 递归打印所有元素
element.print();
}
}
}
/**
* 课程元素的print方法
*/
@Override
public void print() {
System.out.println("课程名称:" + this.getName(this));
}
- 拓展
jdk中HashMap和ArrayList都可以可以使用addAll()方法把容器对象加入另外一个容器对象里面形成新的对象。
- 总结
组合模式下的外部使用较为方便,但是具体实现比较复杂。