快速导航
一、组合模式介绍
二、代码演示
三、jdk中使用组合模式的地方
一、组合模式介绍
定义:将对象组合成树形结构以表示“部分-整体”的层次结构
组合模式使客户端对单个对象和组合对象保持一致的方式处理
类型:结构型
适用场景:
希望客户端可以忽略组合对象与单个对象的差异时
处理一个树形结构时
优点:
清楚的定义分层次的复杂对象,表示对象的全部或部分层次
让客户端忽略层次的差异,方便对整个层次结构进行控制
简化 客户端代码
符合开闭原则
缺点:
限制类型时会较为复杂
使设计变得更为抽象
相关设计模式:
组合模式和访问者模式
二、代码演示
/**
* @program: adpn-pattern->CourseComponent
* @description: 抽象父类
* @author: Jstar
* @create: 2019-11-30 09:35
**/
public abstract class CatalogComponent {
public void add(CatalogComponent catalogComponent){};
public void remove(CatalogComponent catalogComponent){};
public String getName(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("无法获取名称");
};
public double getPrice(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("无法获取价格");
};
public void print(){};
}
/**
* @program: adpn-pattern->CourseCatalog
* @description: 目录类
* @author: Jstar
* @create: 2019-11-30 09:39
**/
public class CourseCatalog extends CatalogComponent {
List<CatalogComponent> items= new ArrayList<CatalogComponent>();
private String name;
public CourseCatalog(String name) {
this.name = name;
}
@Override
public void add(CatalogComponent catalogComponent) {
items.add(catalogComponent);
}
@Override
public void remove(CatalogComponent catalogComponent) {
items.remove(catalogComponent);
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public void print() {
System.out.println(this.name);
for (int i = 0; i < items.size(); i++) {
items.get(i).print();
}
}
}
/**
* @program: adpn-pattern->Course
* @description: 课程类
* @author: Jstar
* @create: 2019-11-30 09:40
**/
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("课程名称:"+this.name+" 价格:"+this.price);
}
}
//测试类
public class Test {
public static void main(String[] args) {
CatalogComponent javaCourse=new Course("java课程",105);
CatalogComponent pythonCourse=new Course("python课程",200);
CatalogComponent sourceCatalog=new CourseCatalog("语言学习目录");
sourceCatalog.add(javaCourse);
sourceCatalog.add(pythonCourse);
CatalogComponent csdnCatalog=new CourseCatalog("csdn学习目录");
CatalogComponent csdnC1=new Course("csdn人工智能",300);
CatalogComponent csdnC2=new Course("csdn大数据",900);
csdnCatalog.add(csdnC1);
csdnCatalog.add(csdnC2);
csdnCatalog.add(sourceCatalog);
csdnCatalog.print();
}
}
看一下类的uml图:
执行结果:
使用组合模式最关键的一点:叶子对象和组合对象都要继承相同的接口或实现相同的抽象类。只有这样才能将叶子对象和组合对象进行一致的处理。
三、jdk中使用组合模式的地方
1、java.awt.Container
Container 继承 Component抽象类:
在 add() 方法中 将 Component 作为参数,形成树状结构:
2、java.util.HashMap
HashMap实现了 Map 接口:
putAll() 方法中又将 Map 作为参数:
3、java.util.ArrayList
ArrayList 实现了 List ,而List 实现了 Collection 接口:
ArrayList 的 addAll() 方法将 Collection 作为参数,是一种组合模式。