一,定义
组合模式,将对象组合成树形结构以表示”部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
Component:为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为,声明一个接口用户访问和管理Component的子部件
Leaf:表示组合中叶节点对象,叶节点没有子节点。
Composite:定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件相关的操作,比如Add和Remove
二,示例
实现一个总公司,分公司,部门的结构职责展示。
abstract class Company {
protected String name;
public Company(String name){
this.name = name;
}
public String depthChar(String sChar,int depth){
StringBuilder builder = new StringBuilder();
for (int i = 0;i < depth;i++){
builder.append(sChar);
}
return builder.toString();
}
public abstract void add(Company company);//增加
public abstract void remove(Company company);//删除
public abstract void display(int depth);//深度
public abstract void lineDuty();//职责
}
/**
* @类描述:具体子公司
*/
public class ConcreteCompany extends Company {
private List<Company> children = new ArrayList<>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void add(Company company) {
children.add(company);
}
@Override
public void remove(Company company) {
children.remove(company);
}
@Override
public void display(int depth) {
System.out.println(depthChar("- ",depth) + name);
for (Company component : children) {
component.display(depth + 2);
}
}
@Override
public void lineDuty() {
for (Company component : children) {
component.lineDuty();
}
}
}
/**
* @类描述:财务部
*/
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
System.out.println(depthChar("- ",depth) + name);
}
@Override
public void lineDuty() {
System.out.println(name + " 公司财务收支管理");
}
}
/**
* @类描述:Hr部门
*/
public class HrDepartment extends Company {
public HrDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int depth) {
System.out.println(depthChar("- ",depth) + name);
}
@Override
public void lineDuty() {
System.out.println(name + " 员工招聘培训管理");
}
}
//test main
//组合模式
public static void compositeModel(){
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HrDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
ConcreteCompany company1 = new ConcreteCompany("上海华东分公司");
company1.add(new HrDepartment("华东分公司人力资源部"));
company1.add(new FinanceDepartment("华东分公司财务部"));
root.add(company1);
ConcreteCompany company2 = new ConcreteCompany("南京办事处");
company2.add(new HrDepartment("南京办事处人力资源部"));
company2.add(new FinanceDepartment("南京办事处财务部"));
company1.add(company2);
ConcreteCompany company3 = new ConcreteCompany("杭州办事处");
company3.add(new HrDepartment("杭州办事处人力资源部"));
company3.add(new FinanceDepartment("杭州办事处财务部"));
company1.add(company3);
System.out.println("结构图:");
root.display(1);
System.out.println("\n职责:");
root.lineDuty();
}
输出结果:
结构图:
- 北京总公司
- - - 总公司人力资源部
- - - 总公司财务部
- - - 上海华东分公司
- - - - - 华东分公司人力资源部
- - - - - 华东分公司财务部
- - - - - 南京办事处
- - - - - - - 南京办事处人力资源部
- - - - - - - 南京办事处财务部
- - - - - 杭州办事处
- - - - - - - 杭州办事处人力资源部
- - - - - - - 杭州办事处财务部
职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理
三,总结
1,需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同。统一的使用组合结构中的所有对象时。可以考虑使用组合模式。
2,基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断递归下去,客户代码中,任何用到基本对象的地方,都可以使用组合对象。
3,用户是不用关系到底是处理一个叶节点还是处理一个组合组件,也用不着为定义组合而写一些判断语句了。
4,组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。组合模式可以一致的使用组合结构和单个对象。
参考:《大话设计模式》