设计模式-组合模式

组合模式用于将一组对象组织成树形结构,表示部分-整体关系,使得客户端可以统一处理单个对象和组合对象。文章通过举例说明了为何要使用组合模式,如在设计组织机构时,需要区分单位和部门,以及如何动态管理它们。组合模式通过抽象类和具体类的定义,实现了业务逻辑的简化和扩展性增强。
摘要由CSDN通过智能技术生成

组合模式



什么是组合模式

  将一组对象组织(Compose)成树形结构,以表示一种“部分 - 整体”的层次结构。组合让客户端(在很多设计模式书籍中,“客户端”代指代码的使用者。)可以统一单个对象和组合对象的处理逻辑。


为什么要用组合模式

假如说我们现在有这样一个需求,设计一个类来表示组织机构,能方便地实现下面这些功能:

  • 组织机构可以区分单位和部门,部门下不可设子部门
  • 动态地添加、删除某个组织机构下的子组织机构;
  • 统计指定组织机构下的组织机构个数;

我们用代码示例如下:

public class Organization {
    private String name;
    private Boolean isDepartment;
    private List<Organization> subOrganizations = new ArrayList<>();

    public Organization(String name, boolean isDepartment) {
        this.name = name;
        this.isDepartment = isDepartment;
    }

    public int countNumOfOrganizations() {
        if (isDepartment) {
            return 1;
        }
        int numOfOrganizations = 0;
        for (Organization organization : subOrganizations) {
            numOfOrganizations += organization.countNumOfOrganizations();
        }
        return numOfOrganizations;
    }

    public void addSubOrganization(Organization organization) {
        subOrganizations.add(organization);
    }

    public void removeSubOrganizations(Organization organization) {
        int size = subOrganizations.size();
        int i = 0;
        for (; i < size; ++i) {
            if (subOrganizations.get(i).getName().equalsIgnoreCase(organization.getName())) {
                break;
            }
        }
        if (i < size) {
            subOrganizations.remove(i);
        }
    }
}

  单纯从功能实现角度来说,上面的代码没有问题,已经实现了我们想要的功能。但是,如果我们开发的是一个大型系统,从扩展性(单位或部门可能会对应不同的操作)、业务建模(单位和部门从业务上是两个概念)、代码的可读性(单位和部门区分对待更加符合人们对业务的认知)的角度来说,我们最好对单位和部门进行区分设计,定义为 Unity和 Department 两个类。
  按照这个设计思路,我们对代码进行重构。重构之后的代码如下所示:

// 组织机构抽象类
public abstract class Organization {
    private String name;
    public Organization(String namet) {
        this.name = name;
    }
    public abstract int countNumOfOrganizations();
}

// 部门具象类(不存在子节点)
public class Department extends Organization {
    public Department(String namet) {
        super(namet);
    }
    @Override
    public int countNumOfOrganizations() {
        return 1;
    }
}

// 单位具象类(存在子节点)
public class Unity extends Organization{
    private List<Organization> subOrganizations = new ArrayList<>();
    public Unity(String name) {
        super(name);
    }
    @Override
    public int countNumOfOrganizations() {
        int numOfOrg = 0;
        for (Organization subOrganization : subOrganizations) {
            numOfOrg += subOrganization.countNumOfOrganizations();
        }
        return numOfOrg;
    }

    public void addSubOrganization(Organization organization) {
        subOrganizations.add(organization);
    }

    public void removeSubOrganizations(Organization organization) {
        int size = subOrganizations.size();
        int i = 0;
        for (; i < size; ++i) {
            if (subOrganizations.get(i).getName().equalsIgnoreCase(organization.getName())) {
                break;
            }
        }
        if (i < size) {
            subOrganizations.remove(i);
        }
    }
}

如何使用组合模式

组合模式的用法比较固定,可以分为一下三个角色:

  • 抽象父类:用来定义共有属性与方法,例如上面代码示例中的Organization;
  • 具象叶子类:用来定义具象的叶子类,一般直接继承抽象父类并复写其抽象方法,例如上面代码示例中的Department;
  • 具象组合类:用来定义具象的组合类,一般在继承父类的基础上增加组合相关操作,例如上面代码示例中的Unity;
    在这里插入图片描述

总结

  组合模式的设计思路,与其说是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。
  组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值