组合模式参考程杰《大话设计模式》
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
当需求中是体现部分与整体层次的结构,希望用户忽略组合对象与单个对象的不同,统一的使用组合结构中对象时,就可以考虑组合模式。
比如文件和文件夹,在复制粘贴时操作的可能是文件也可能是文件夹。比如公司的部门和分公司的部门。都是需要表示部分和整体,而在使用上有一致性。
透明方式:Component中声明所有用来管理子对象的方法,其中包括add,remove等。其子类都有这些接口。这样做的好处就是叶节点和枝节点没有任何区别,他们具备完全一致的行为接口。但Leaf中实际上本身是不需要add,remove方法的,实现它们没有意义。
安全方式:Component中不声明add,remove,子节点不必实现这些方法,而在Composite声明所有用来管理子类对象的方法。不过由于不够透明,所以叶节点和枝节点有不同的接口,客户端调用时要做相应的判断。
实例以总公司,分公司和公司的各个部门为例
Component类
public abstract class Company {
private String name;
public Company(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void addCompany(Company company);
public abstract void removeCompany(Company company);
public abstract void DoSomething();
public abstract void Display(int depth);
}
两个部门类,即Leaf类
public class HRDepartment extends Company{
public HRDepartment(String name) {
super(name);
}
@Override
public void addCompany(Company company) {
}
@Override
public void removeCompany(Company company) {
}
@Override
public void DoSomething() {
System.out.println(super.getName() + "人力资源部门负责招聘");
}
@Override
public void Display(int depth) {
System.out.println(depth + " " + super.getName());
}
}
public class ITDepartment extends Company {
public ITDepartment(String name) {
super(name);
}
@Override
public void addCompany(Company company) {
}
@Override
public void removeCompany(Company company) {
}
@Override
public void DoSomething() {
System.out.println(super.getName() + "IT部门负责维修电脑");
}
@Override
public void Display(int depth) {
System.out.println(depth + " " + super.getName());
}
}
分公司,即Composite类
public class ConcreteCompany extends Company {
private List companies = new ArrayList();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void addCompany(Company company) {
companies.add(company);
}
@Override
public void removeCompany(Company company) {
companies.remove(company);
}
@Override
public void DoSomething() {
for (Company c : companies
) {
c.DoSomething();
}
}
@Override
public void Display(int depth) {
System.out.println(depth + " " + super.getName());
for (Company c : companies
) {
c.Display(depth + 1);
}
}
}
主方法,使用
public class Demo1Application {
public static void main(String[] args) {
ConcreteCompany root = new ConcreteCompany("总公司");
ConcreteCompany branch = new ConcreteCompany("分公司");
branch.addCompany(new HRDepartment("分公司人力"));
branch.addCompany(new ITDepartment("分公司IT"));
root.addCompany(branch);
root.addCompany(new HRDepartment("总公司人力"));
root.addCompany(new ITDepartment("总公司IT"));
root.DoSomething();
root.Display(1);
}
}
输出结果



