介绍Java组合模式
本文我们探讨一种结构设计模式————组合模式。学习其结构及实现目的。
组合模式结构
组合模式用于以相同的方式处理单个对象和对象的组合(或复合)。可以视为树形结构,都继承一个基类,能表示单个部分或整个对象层次。可以分解为几个部分:
- 组件:在组合中所有对象的基础接口。其可以是接口或抽象类,包括管理子组合的通用方法。
- 叶子节点:实现基础组件的缺省行为,不包括对其他对象的引用。
- 组合节点:拥有叶子节点。实现基础组件的方法并定义子节点集合相关操作。
- 客户端:通过基础组件接口访问组合元素。
示例实现
下面我们进一步通过实现进行阐述。假设我们构建一个层次结构————公司组织机构。
基础组件接口
对基础组件接口,我们定义一个简单printDepartmentName方法:
public interface Department {
void printDepartmentName();
}
叶子组件
对于叶子组件,我们定义财务部和销售部类:
public class FinancialDepartment implements Department {
private Integer id;
private String name;
public void printDepartmentName() {
System.out.println(getClass().getSimpleName());
}
// standard constructor, getters, setters
}
第二个叶子组件类:
public class SalesDepartment implements Department {
private Integer id;
private String name;
public void printDepartmentName() {
System.out.println(getClass().getSimpleName());
}
// standard constructor, getters, setters
}
两个类都实现了基础组件的printDepartmentName方法,打印各自类的名称。另外,因为是叶子组件,所以不包含其他部门对象。接下来看组合节点。
组合节点
因为是组合节点,我们创建HeadDepartment类:
public class HeadDepartment implements Department {
private Integer id;
private String name;
private List<Department> childDepartments;
public HeadDepartment(Integer id, String name) {
this.id = id;
this.name = name;
this.childDepartments = new ArrayList<>();
}
public void printDepartmentName() {
childDepartments.forEach(Department::printDepartmentName);
}
public void addDepartment(Department department) {
childDepartments.add(department);
}
public void removeDepartment(Department department) {
childDepartments.remove(department);
}
}
该类包含Department 组件集合以及对list的操作方法。
组合节点的printDepartmentName方法实现是通过迭代集合中叶子节点并执行其相应方法。
测试
为了测试,我们定义一个类:
public class CompositeDemo {
public static void main(String args[]) {
Department salesDepartment = new SalesDepartment(
1, "Sales department");
Department financialDepartment = new FinancialDepartment(
2, "Financial department");
HeadDepartment headDepartment = new HeadDepartment(
3, "Head department");
headDepartment.addDepartment(salesDepartment);
headDepartment.addDepartment(financialDepartment);
headDepartment.printDepartmentName();
}
}
首先我们创建财务部和销售部两个实例。然后实例化总部并给其增加前面创建的两个对象。最后测试printDepartmentName组件方法,与期望一致,方法输出包括每个叶子组件的名称。
SalesDepartment
FinancialDepartment
总结
本文我们学习了组合设计模式,重点描述其主要结构并通过示例说明其用法。实际应用中如文件和目录,GUI中的容器和组件等都有可能会使用该模式。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/89762835