Java组合模式详解
什么是组合模式?
组合模式是一种结构型设计模式,其主要思想是将对象组合成树形结构以表示“部分整体”的层次结构。组合模式中包含两种基本的组件:
- 叶节点(Leaf): 叶节点代表树的最底层的节点,即无子节点的节点。
- 复合节点(Composite): 复合节点代表树的非叶子节点,它可能包含子节点,也可能不包含。
组合模式的优点
- 可以更方便地扩展对象结构;
- 对象与对象集合使用起来方便一致;
- 简化了实现客户端代码的复杂性。
Java组合模式的实现方式
我们可以通过抽象类和接口的方式进行组合模式的实现。以员工管理为例,假设员工管理有以下两种类型的员工:
- 普通员工(Leaf节点)
- 经理(Composite节点)
我们可以定义一个抽象类把员工类型进行统一。该类可以是抽象类或者是接口:
abstract class Employee {
private String name;
private Department department;
public Employee(String name, Department department) {
this.name = name;
this.department = department;
}
public String getName() {
return name;
}
public Department getDepartment() {
return department;
}
// 其他操作
// ...
/**
* 添加员工
*
* @param employee 新增员工
*/
public void add(Employee employee) {
throw new UnsupportedOperationException("add");
}
/**
* 删除员工
*
* @param employee 删除的员工
*/
public void remove(Employee employee) {
throw new UnsupportedOperationException("remove");
}
/**
* 打印员工
*
* @param depth 打印深度
*/
public abstract void print(int depth);
}
在抽象类中,我们定义了员工的名称和所属部门属性,并定义了是否是叶子节点方法和添加、删除、打印操作的抽象方法。
在这个抽象类中,并没有实现添加、删除和打印的具体操作,因为普通员工没有子员工,所以这些操作不支持对普通员工的操作。而对于经理节点,因其下面有可能包含一些子员工,因此需要重写这些方法:
class Manager extends Employee {
private List<Employee> employees = new ArrayList<>();
public Manager(String name, Department department) {
super(name, department);
}
/**
* 添加员工
*
* @param employee 新增员工
*/
@Override
public void add(Employee employee) {
employees.add(employee);
}
/**
* 删除员工
*
* @param employee 删除的员工
*/
@Override
public void remove(Employee employee) {
employees.remove(employee);
}
/**
* 打印员工
*
* @param depth 打印深度
*/
@Override
public void print(int depth) {
System.out.println("depth:" + depth + ", name:" + getName());
for (Employee employee : employees) {
employee.print(depth + 1);
}
}
}
在这个实现中,Manager继承了我们定义的Employee类,并且重写了add、remove和print操作。我们可以发现,其下面定义了员工列表,这个列表中可以添加其他的Employee类型实例,也就是说,Manager可以添加其他的经理和普通员工实例。
由于普通员工没有子员工,因此它可以不重写add、remove和print方法。
组合模式的使用场景
组合模式通常需要满足以下两个条件:
- 应用程序需要表示部分和整体层次关系;
- 应用程序需要从客户端比较同一组别的对象。
例如:
- 文件系统的目录和文件;
- 组织结构图和员工;
- 菜单、子菜单和菜单项等界面元素。
例子一:组织结构图和员工
我们假设一个公司有多个部门,每个部门中有多个员工,公司最高管理者是CEO。我们可以用组合模式来表达出这些关系。
Department marketing = new Department("Marketing");
Department rd = new Department("Research and Development");
Department finance = new Department("Finance");
Employee ceo = new Manager("William", marketing);
Employee cto = new Manager("Marshall", rd);
Employee cfo = new Manager("Peeters", finance);
ceo.add(cto);
ceo.add(cfo);
Employee staff1 = new Manager("Andy", marketing);
Employee staff2 = new Manager("Simon", marketing);
Employee staff3 = new Manager("Kate", rd);
Employee staff4 = new Manager("Bob", finance);
cto.add(staff1);
cto.add(staff2);
cfo.add(staff3);
cfo.add(staff4);
ceo.print(0);
执行上述代码可以得到如下输出:
depth:0, name:William
depth:1, name:Marshall
depth:2, name:Andy
depth:2, name:Simon
depth:1, name:Peeters
depth:2, name:Kate
depth:2, name:Bob
例子二:煎饼糖果店销售情况
我们假设有一个煎饼糖果店,这家店面积不大,但是它有煎饼、糖果和饮料等多种商品,我们对这些商品进行销售管理。
MenuItem pancake = new MenuItem("Pancake", "A delicious pancake with maple syrup", 2.99);
MenuItem candy = new MenuItem("Candy", "Candy with many flavors", 1.99);
MenuItem drink = new MenuItem("Drink", "Drinks and juices", 0.99);
MenuComponent menu = new Menu("Menu");
menu.add(pancake);
menu.add(candy);
menu.add(drink);
MenuComponent combo = new Menu("Combo");
MenuItem pancakeCombo = new MenuItem("Pancake Combo", "A delicious pancake with maple syrup and coffee or tea", 4.99);
MenuItem candyCombo = new MenuItem("Candy Combo", "Candy with many flavors and coffee or tea", 3.99);
combo.add(pancakeCombo);
combo.add(candyCombo);
combo.add(drink);
menu.add(combo);
menu.print();
执行上述代码可以得到如下输出:
Menu:
Pancake A delicious pancake with maple syrup $2.99
Candy Candy with many flavors $1.99
Drink Drinks and juices $0.99
Combo:
Pancake Combo A delicious pancake with maple syrup and coffee or tea $4.99
Candy Combo Candy with many flavors and coffee or tea $3.99
Drink Drinks and juices $0.99
总结
组合模式主要用于树形结构的处理,它将对象组织成树形结构,并且能够以同样的方式处理单个对象以及对象集合,从而让客户端用一致性的方式处理对象。组合模式是设计渐进式的设计策略,即它允许我们逐步地将简单的对象组合成更为复杂的对象结构。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java设计模式之java组合模式详解 - Python技术站