需求中是体现部分与总体层次的结构时,以及你但愿用户能够忽略组合对象与单个对象的不一样,统一地使用组合结构中的全部对象时,就应该考虑使用组合模式了——《大话设计模式》html
能够用于树结构的数据上,好比公司层级,树形文件系统等。java
公司架构是总公司下有人力资源部和财务部以及分公司,分公司下有人力资源部和财务部已经下属的办事处,办事处下属也有人力资源和财务部,对公司架构能够分析总结出,一共分为实体公司部门(分支节点),好比分公司、总公司、办事处,人力资源部门和财务部(叶子节点),各办事处、分公司都有单独设置。编程
首先抽象一层公司的描述:设计模式
public abstract class Company { protected String name; public Company(String name) { this.name = name; } public abstract void add(Company c); public abstract void remove(Company c); public abstract void display(int depth); //显示 public abstract void lineOfDuty(); //履行职责 }
实现一个普通的公司描述:架构
public class ConcreteCompany extends Company { private List<Company> children = new ArrayList(); public ConcreteCompany(String name) { super(name); } @Override public void add(Company c) { children.add(c); } @Override public void remove(Company c) { children.remove(c); } @Override public void display(int depth) { Printer.print(depth, this.name); for (Company c : children) { c.display(depth + 2); } } @Override public void lineOfDuty() { for (Company c : children) { c.lineOfDuty(); } } }
人力资源和财务部的实现:app
public class HrDepartment extends Company { public HrDepartment(String name) { super(name); } @Override public void add(Company c) { } @Override public void remove(Company c) { } @Override public void display(int depth) { Printer.print(depth,this.name); } @Override public void lineOfDuty() { System.out.println(String.format("%s 员工招聘培训管理", this.name)); } }
public class FinanceDepartment extends Company { public FinanceDepartment(String name) { super(name); } @Override public void add(Company c) { } @Override public void remove(Company c) { } @Override public void display(int depth) { Printer.print(depth, this.name); } @Override public void lineOfDuty() { System.out.println(String.format("%s 公司财务收支管理", this.name)); } }
另外增长一个打印的辅助工具类:ide
public class Printer { public static void print(int dept,String label) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < dept; i++) { builder.append(" - "); } System.out.println(builder.toString() + label); } }
运行上述的例子:工具
@Test public void testComposite(){ ConcreteCompany root = new ConcreteCompany("北京总公司"); root.add(new HrDepartment("总公司人力资源部")); root.add(new FinanceDepartment("总公司财务部")); ConcreteCompany comp = new ConcreteCompany("上海华东分公司"); comp.add(new HrDepartment("华东分公司人力资源部")); comp.add(new FinanceDepartment("华东分公司财务部")); root.add(comp); ConcreteCompany comp1 = new ConcreteCompany("南京办事处"); comp1.add(new HrDepartment("南京办事处人力资源部")); comp1.add(new FinanceDepartment("南京办事处财务部")); comp.add(comp1); ConcreteCompany comp2 = new ConcreteCompany("杭州办事处"); comp2.add(new HrDepartment("杭州办事处人力资源部")); comp2.add(new FinanceDepartment("杭州办事处财务部")); comp.add(comp2); root.display(1); root.lineOfDuty(); }
运行结果为:ui
- 北京总公司 - - - 总公司人力资源部 - - - 总公司财务部 - - - 上海华东分公司 - - - - - 华东分公司人力资源部 - - - - - 华东分公司财务部 - - - - - 南京办事处 - - - - - - - 南京办事处人力资源部 - - - - - - - 南京办事处财务部 - - - - - 杭州办事处 - - - - - - - 杭州办事处人力资源部 - - - - - - - 杭州办事处财务部 总公司人力资源部 员工招聘培训管理 总公司财务部 公司财务收支管理 华东分公司人力资源部 员工招聘培训管理 华东分公司财务部 公司财务收支管理 南京办事处人力资源部 员工招聘培训管理 南京办事处财务部 公司财务收支管理 杭州办事处人力资源部 员工招聘培训管理 杭州办事处财务部 公司财务收支管理 Process finished with exit code 0
组合模式的优势:this
组合模式的缺点:
在如下状况下可使用组合模式:
本文参考了《大话设计模式》 和 https://www.cnblogs.com/Bobby0322/p/4191895.html