什么是组合模式
- 组合模式也叫合成模式,用于描述局部和整体的关系
- 将对象组合成树形结构以展示“部分-整体”的层次结构,似的用户对单个对象和组合对象的使用具有一致性。
组合模式的几个角色
- Component抽象构件角色
- 定义参加组合对象的共有属性和方法,可以定义一些默认的行为或属性
- Leaf叶子构件
- 叶子对象,其下再也没有其他的分支,也就是遍历的最小单位
- Composite树枝构件
- 树枝对象,作用是组合树枝节点和叶子节点形成一个属性结构
- Component抽象构件角色
代码示例
- 鉴于组合模式描述的是部分和整体之间的关系,描述树形结构,那么示例则描述了我们最常见的公司组织人员的职位结构,使得代码具有较好的参照性
package com.pattern.composite;
/**
* 组织人员的公共结构,所有类型都要实现这个接口
* @author yjzhou
*/
public interface ICorp {
String getInfo();
}
package com.pattern.composite;
import java.util.ArrayList;
import java.util.List;
/**
* 分支抽象类,可以表示经理或者CEO等
* @author yjzhou
*/
public interface IBranch extends ICorp{
//能够增加普通职工,或者经理
public void addSubordinate(ICorp corp);
//获取下属的信息
public List<ICorp> getSubordinate();
}
package com.pattern.composite;
/**
* 叶子抽象,用于表示普通员工
* @author yjzhou
*/
public interface ILeaf extends ICorp{
}
package com.pattern.composite;
import java.util.ArrayList;
import java.util.List;
/**
* 分支实现类
* @author yjzhou
*/
public class Branch implements IBranch {
//领导人的名字
private String name = "";
//职位
private String position = "";
//薪资
private int salary = 0;
List<ICorp> subOrdinateList = new ArrayList<ICorp>();
public Branch(String name, String position, int salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
@Override
public void addSubordinate(ICorp corp) {
this.subOrdinateList.add(corp);
}
@Override
public List<ICorp> getSubordinate() {
return this.subOrdinateList;
}
@Override
public String getInfo() {
String info = "";
info = "姓名:" + this.name;
info += "\t职位:" + this.position;
info += "\t薪资:" + this.salary;
return info;
}
}
package com.pattern.composite;
/**
* 叶子实现类
* @author yjzhou
*/
public class Leaf implements ILeaf {
//员工名称
private String name;
//职位
private String position;
//薪资
private int salary = 0;
public Leaf(String name, String position, int salary) {
this.name = name;
this.position = position;
this.salary = salary;
}
@Override
public String getInfo() {
String info = "";
info = "姓名:" + this.name;
info += "\t职位:" + this.position;
info += "\t薪资:" + this.salary;
return info;
}
}
package com.pattern.composite;
import java.util.List;
/**
* Created by Lenovo.
*/
public class Client {
public static void main(String[] args) {
Branch ceo = compositeCorpTree();
System.out.println(ceo.getInfo());
System.out.println(getTreeInfo(ceo));
}
public static Branch compositeCorpTree() {
//产生CEO
Branch root = new Branch("王大麻子", "总经理", 100000);
//产生部门经理
Branch developDep = new Branch("刘大瘸子", "研发部门经理", 10000);
Branch salesDep = new Branch("马二拐子", "销售部门经理", 20000);
Branch financeDep = new Branch("赵三驼子", "财务部门经理", 30000);
//产生小组长
Branch firstDevGroup = new Branch("", "", 5000);
Branch secondDevGroup = new Branch("", "", 6000);
//普通员工
Leaf a = new Leaf("a", "开发人员", 2000);
Leaf b = new Leaf("b", "开发人员", 2000);
Leaf c = new Leaf("c", "开发人员", 2000);
Leaf d = new Leaf("d", "开发人员", 2000);
Leaf e = new Leaf("e", "开发人员", 2000);
Leaf f = new Leaf("f", "开发人员", 2000);
Leaf g = new Leaf("g", "开发人员", 2000);
Leaf h = new Leaf("h", "销售人员", 5000);
Leaf i = new Leaf("i", "销售人员", 4000);
Leaf j = new Leaf("j", "财务人员", 5000);
Leaf k = new Leaf("k", "CEO秘书", 8000);
Leaf zhengLaoLiu = new Leaf("郑老六", "研发部副经理", 20000);
//组装
//CEO下有三个部门经理和一个秘书
root.addSubordinate(k);
root.addSubordinate(developDep);
root.addSubordinate(salesDep);
root.addSubordinate(financeDep);
//研发部经理
developDep.addSubordinate(zhengLaoLiu);
developDep.addSubordinate(firstDevGroup);
developDep.addSubordinate(secondDevGroup);
//看看两个开发小组下有什么
firstDevGroup.addSubordinate(a);
firstDevGroup.addSubordinate(b);
firstDevGroup.addSubordinate(c);
secondDevGroup.addSubordinate(d);
secondDevGroup.addSubordinate(e);
secondDevGroup.addSubordinate(f);
//再看销售部下的人员情况
salesDep.addSubordinate(h);
salesDep.addSubordinate(i);
//最后一个财务
financeDep.addSubordinate(j);
return root;
}
//遍历整个组织结构
public static String getTreeInfo(Branch root){
List<ICorp> subordinateList = root.getSubordinate();
String info = "";
for(ICorp s :subordinateList){
if(s instanceof Leaf){
//是员工就直接获得信息
info = info + s.getInfo()+"\n";
}else{
//是个小头目
info = info + s.getInfo() +"\n"+ getTreeInfo((Branch)s);
}
}
return info;
}
}