组合模式介绍
组合模式有时候又叫做部分-整体模式,它使我们树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。组合模式可以优化处理递归或分级数据结构。
组合模式的定义
将对象组合成树形结构以表示”部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式的使用场景
表示对象的部分-整体层次结构时
从一个整体中能够独立出部分模块或功能的场景
组合模式的UML类图
代码示例:
//公司抽象类
public abstract class Company {
private String name;
public Company(String name){
this.name = name;
}
public Company(){
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
protected abstract void add(Company company);
protected abstract void remove(Company company);
protected abstract void display(int depth);
}
public class ConcreteCompany extends Company {
private List<Company> cList;
public ConcreteCompany() {
cList = new ArrayList<>();
}
public ConcreteCompany(String name){
super(name);
cList = new ArrayList<>();
}
@Override
protected void add(Company company) {
cList.add(company);
}
@Override
protected void remove(Company company) {
cList.remove(company);
}
@Override
protected void display(int depth) {
StringBuffer sBuffer = new StringBuffer();
for(int i = 0;i < depth ;i++){
sBuffer.append("-");
}
System.out.println(new String(sBuffer) + this.getName());
for(Company c : cList){
c.display(depth + 2);
}
}
}
public class FinanceDepartment extends Company {
public FinanceDepartment() {
}
public FinanceDepartment(String name){
super(name);
}
@Override
protected void add(Company company) {
}
@Override
protected void remove(Company company) {
}
@Override
protected void display(int depth) {
StringBuffer sb = new StringBuffer("");
for(int i = 0 ; i < depth; i++){
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
}
}
public class HRDepartment extends Company {
public HRDepartment() {
}
public HRDepartment(String name){
super(name);
}
@Override
protected void add(Company company) {
}
@Override
protected void remove(Company company) {
}
@Override
protected void display(int depth) {
StringBuffer sb =new StringBuffer("");
for(int i = 0 ; i < depth ; i++){
sb.append("-");
}
System.out.println(new String(sb) + this.getName());
}
}
public class Client {
public static void main(String[] args) {
Company root = new ConcreteCompany();
root.setName("深圳总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
Company shandongCom = new ConcreteCompany("山东分公司");
shandongCom.add(new HRDepartment("山东分公司人力资源部"));
shandongCom.add(new FinanceDepartment("山东分公司账务部"));
Company zaozhuangCom = new ConcreteCompany("枣庄办事处");
zaozhuangCom.add(new FinanceDepartment("枣庄办事处财务部"));
zaozhuangCom.add(new HRDepartment("枣庄办事处人力资源部"));
Company jinanCom = new ConcreteCompany("济南办事处");
jinanCom.add(new FinanceDepartment("济南办事处财务部"));
jinanCom.add(new HRDepartment("济南办事处人力资源部"));
shandongCom.add(jinanCom);
shandongCom.add(zaozhuangCom);
Company huadongCom = new ConcreteCompany("上海华东分公司");
huadongCom.add(new HRDepartment("上海华东分公司人力资源部"));
huadongCom.add(new FinanceDepartment("上海华东分公司账务部"));
Company hangzhouCom = new ConcreteCompany("杭州办事处");
hangzhouCom.add(new FinanceDepartment("杭州办事处财务部"));
hangzhouCom.add(new HRDepartment("杭州办事处人力资源部"));
Company nanjingCom = new ConcreteCompany("南京办事处");
nanjingCom.add(new FinanceDepartment("南京办事处财务部"));
nanjingCom.add(new HRDepartment("南京办事处人力资源部"));
huadongCom.add(hangzhouCom);
huadongCom.add(nanjingCom);
root.add(shandongCom);
root.add(huadongCom);
root.display(0);
}
}
涉及角色:
1.Company是组合中的对象声明的抽象类,也是总结点
2.ConcreteCompany是组合中的枝节点
3.FinanceDepartment,HRDepartment是组合中的叶子节点
运行结果:
深圳总公司
–总公司人力资源部
–总公司财务部
–山东分公司
—-山东分公司人力资源部
—-山东分公司账务部
—-济南办事处
——济南办事处财务部
——济南办事处人力资源部
—-枣庄办事处
——枣庄办事处财务部
——枣庄办事处人力资源部
–上海华东分公司
—-上海华东分公司人力资源部
—-上海华东分公司账务部
—-杭州办事处
——杭州办事处财务部
——杭州办事处人力资源部
—-南京办事处
——南京办事处财务部
——南京办事处人力资源部
总结
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以处理简单元素一样来处理复杂元素一样来处理,如果你想要创建层次结构,并可以在其中以相同的方式对待所以元素,那么组合模式是最理想的选择,本示例代码使用的一个公司的列子来说明组合模式的用途。