1.定义
将对象组合成树形结构以表示“整体—部分”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
2.使用场景
部分、整体场景,如树形菜单,文件、文件夹的管理。
例如: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
3.实现
/**
* 抽象构件(Component)角色:HumanResource是部门类(Department)和员工类(Employee)抽象出来的父类,为的是能统一薪资的处理逻辑。
* @author Administrator
*
*/
public abstract class HumanResource {
protected long id;
protected double salary;
public HumanResource(long id) {
// TODO Auto-generated constructor stub
this.id = id;
}
public long getId() {
return id;
}
public abstract double calcuateSalary();
}
/**
* 树枝构件(Composite)角色 / 中间构件:Department是组合中的树枝对象,它拥有子节点,可以添加、删除子节点。
* @author Administrator
*
*/
public class Department extends HumanResource{
private List<HumanResource> list = new ArrayList<>();
public Department(long id) {
super(id);
// TODO Auto-generated constructor stub
}
public void addHumanResource(HumanResource hr) {
list.add(hr);
}
public void removeHumanResource(HumanResource hr) {
list.remove(hr);
}
@Override
public double calcuateSalary() {
// TODO Auto-generated method stub
double totalSarlary = 0;
for(HumanResource hr:list) {
totalSarlary +=hr.calcuateSalary();
}
this.salary = totalSarlary;
return totalSarlary;
}
}
/**
* 树叶构件(Leaf)角色:是组合中的叶节点对象,不再拥有子节点,是树状结构最底层的叶子。
* @author Administrator
*
*/
public class Employee extends HumanResource{
public Employee(long id,double salary) {
super(id);
// TODO Auto-generated constructor stub
this.salary = salary;
}
@Override
public double calcuateSalary() {
// TODO Auto-generated method stub
return salary;
}
}
/**
* 测试类
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Employee ep1 = new Employee(1111,1000);
Employee ep2 = new Employee(1222,1000);
Employee ep3 = new Employee(2222,2000);
Employee ep4 = new Employee(2333,2000);
Department depart1 = new Department(1001);
depart1.addHumanResource(ep1);
depart1.addHumanResource(ep2);
Department depart2 = new Department(1002);
depart2.addHumanResource(ep3);
depart2.addHumanResource(ep4);
Department root = new Department(1);
root.addHumanResource(depart1);
root.addHumanResource(depart2);
System.out.println("depart1 salary:"+depart1.calcuateSalary());
System.out.println("depart2 salary:"+depart2.calcuateSalary());
System.out.println("root salary:"+root.calcuateSalary());
}
}
运行结果
4.总结
它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
优点: 1、高层模块调用简单。 2、节点自由增加。
缺点: 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。