设计模式(八)组合模式 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();
    }

 

  • 输出:

 

转载于:https://www.cnblogs.com/jing-an-feng-shao/p/10869709.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值