容许你将对象组合成树形结构来表现“总体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。数据结构
组合模式适用于建立复杂的对象,这个对象包含某些个别的对象以及这些对象的组合。app
从操做的角度而言,客户端对于 个别对象/组合 的操做是一致的。ide
如图所示,总公司下属有多个部门,而子公司能够视为多个部门的组合。ui
整个数据结构呈树状,完美契合组合模式的应用场景。spa
在这个场景中:code
@Data @AllArgsConstructor @ToString public abstract class CompanyItem { protected String name; protected void addCompanyItem(CompanyItem companyItem) { throw new UnsupportedOperationException("Not support to add companyItem"); } protected void removeCompanyItem(CompanyItem companyItem) { throw new UnsupportedOperationException("Not support to remove companyItem"); } protected abstract void lineOfDuty(); protected abstract void showStructure(int depth); }
public final class Company extends CompanyItem { private List<CompanyItem> childCompanyItems = new ArrayList<>(); public Company(String name) { super(name); } @Override public void addCompanyItem(CompanyItem component) { childCompanyItems.add(component); } @Override public void removeCompanyItem(CompanyItem component) { childCompanyItems.remove(component); } @Override public void lineOfDuty() { childCompanyItems.forEach(companyItem -> companyItem.lineOfDuty()); } @Override public void showStructure(int depth) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < depth; ++i) { builder.append("-"); } System.out.println(builder.append(name)); childCompanyItems.forEach(companyItem -> companyItem.showStructure(depth + 1)); } }
public final class FinanceDepartment extends CompanyItem { public FinanceDepartment(String name) { super(name); } @Override public void lineOfDuty() { System.out.println(name + ", treasurer is in charge of payroll"); } @Override public void showStructure(int depth) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < depth; ++i) { builder.append("-"); } System.out.println(builder.append(name)); } }
public final class HRDepartment extends CompanyItem { public HRDepartment(String name) { super(name); } @Override public void lineOfDuty() { System.out.println(name + ", HR is responsible for recruiting new employees"); } @Override public void showStructure(int depth) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < depth; ++i) { builder.append("-"); } System.out.println(builder.append(name)); } }
private CompanyItem createParentCompany() { CompanyItem parentCompany = new Company("Shanghai parent company"); parentCompany.addCompanyItem(new HRDepartment("Parent company HR department")); CompanyItem southChildCompany = new Company("South child company"); southChildCompany.addCompanyItem(new HRDepartment("South child company HR department")); parentCompany.addCompanyItem(southChildCompany); CompanyItem hongKongOffice = new Company("HongKong office"); hongKongOffice.addCompanyItem(new FinanceDepartment("Hongkong office Finance department")); southChildCompany.addCompanyItem(hongKongOffice); parentCompany.addCompanyItem(new FinanceDepartment("Parent company Finance department")); return parentCompany; } @Test void testComposite() { CompanyItem parentCompany = createParentCompany(); parentCompany.showStructure(1); System.out.println("==========================="); parentCompany.lineOfDuty(); }