设计模式组合模式 Composite

Posted jing-an-feng-shao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式组合模式 Composite相关的知识,希望对你有一定的参考价值。

  • 组合模式:

  允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

 

  组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合。

  从操作的角度而言,客户端对于 个别对象/组合 的操作是一致的。

 

  • 模拟场景

技术图片

 

  如图所示,总公司下属有多个部门,而子公司可以视为多个部门的组合。

  整个数据结构呈树状,完美契合组合模式的应用场景。

 

  • UML:

技术图片

  在这个场景中:

  1. 个别对象 -> 人事部(HRDepartment)和财务部(FinanceDepartment)
  2. 个别对象的组合 -> 公司(Company)
  3. 无论是 Company 还是 Department,对于 Client 而言,都被当做 CompanyItem 使用。
  4. 从树形结构来理解,Department 是叶节点,Company 是非叶节点。

 

  • 代码:
@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();
    }

 

  • 输出:

技术图片

 

以上是关于设计模式组合模式 Composite的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之Composite(组合)(转)

JAVA SCRIPT设计模式--结构型--设计模式之Composite组合模式

设计模式 -- 组合模式(Composite)

设计模式学习篇-Composite组合模式

设计模式:组合模式(Composite)

组合模式(Composite Pattern)