设计模式之组合模式

写在前面

本文看下一种结构型设计模式,组合设计模式。

1:介绍

1.1:什么时候使用组合设计模式

当我们有类似于树形结构的需求时,可以考虑使用组合设计模式,比如公司部门层级,有的大部门,下边还有下级部门。

1.2:UML类图

原型设计模式,包含如下元素:

1:Component
    抽象类,定义了统一的操作,可以理解为构建树的Node
2:Leaf
   单一的对象,可以理解为构建树的Leaf
3:Composite
    组合对象,持有组合对象,里面持有一个List,这也正是组合设计模式名称的由来
4:Client
    客户端类,即使用者

设计模式之组合模式_第1张图片

2:实例

源码 。

2.1:场景

公司部门层级,包含分公司。

2.2:程序

  • 定义Component
public abstract class OrganizationComponent {
    private String name;

    public OrganizationComponent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void add(OrganizationComponent organization);

    public abstract OrganizationComponent getChild(String orgName);

    public abstract int getStaffCount();

    @Override
    public String toString() {
        return name;
    }
}
  • composite
public class OrganizationComposite extends OrganizationComponent {

    //很关键,这体现了组合的思想
    private List<OrganizationComponent> organizations = new ArrayList<>();

    public OrganizationComposite(String name) {
        super(name);
    }

    @Override
    public void add(OrganizationComponent organization) {
        organizations.add(organization);
    }

    @Override
    public OrganizationComponent getChild(String orgName) {
        for (OrganizationComponent org : organizations) {
            OrganizationComponent targetOrg = org.getChild(orgName);
            if (targetOrg != null) {
                return targetOrg;
            }
        }
        return null;
    }

    @Override
    public int getStaffCount() {
        int count = 0;
        for (OrganizationComponent organization : organizations) {
            count += organization.getStaffCount();
        }
        return count;
    }
}  
  • leaf(IT部门)
public class ItDepartment extends OrganizationComponent {

    public ItDepartment(String name) {
        super(name);
    }

    @Override
    public int getStaffCount() {
        return 20;
    }

    @Override
    public void add(OrganizationComponent organization) {
        throw new UnsupportedOperationException(this.getName() + "已经是最基本部门,无法增加下属部门");
    }

    @Override
    public OrganizationComponent getChild(String orgName) {
        if (getName().equals(orgName)) {
            return this;
        }
        return null;
    }
}
  • leaf(行政部门)
public class AdminDepartment extends OrganizationComponent {

    public AdminDepartment(String name) {
        super(name);
    }

    @Override
    public int getStaffCount() {
        return 99;
    }

    @Override
    public void add(OrganizationComponent organization) {
//        throw new UnsupportedOperationException(this.getName() + "已经是最基本部门,无法增加下属部门");
        throw new UnsupportedOperationException(this.getName() + "已经是最基本部门,无法增加下属部门");
    }

    @Override
    public OrganizationComponent getChild(String orgName) {
        if (getName().equals(orgName)) {
            return this;
        }
        return null;
    }
}
  • 测试
public class CompositeClient {

    private OrganizationComponent constructOrganization() {
        // 构建总部
        OrganizationComposite headOffice = new OrganizationComposite("总公司");
        // 总部下的叶子节点,行政部和IT部门,都没有下级部门
        AdminDepartment headAdmin = new AdminDepartment("总公司行政部");
        ItDepartment headIt = new ItDepartment("总公司It部");
        headOffice.add(headAdmin);
        headOffice.add(headIt);

        // 构建天津分公司,是非叶子节点,有下级部门
        OrganizationComposite tianjin = new OrganizationComposite("天津分公司");
        AdminDepartment tianjinAdmin = new AdminDepartment("天津分公司行政部");
        ItDepartment tianjinIT = new ItDepartment("天津分公司It部");
        tianjin.add(tianjinAdmin);
        tianjin.add(tianjinIT);

        // 将天津分公司加入到head中
        headOffice.add(tianjin);

        return headOffice;
    }

    @Test
    public void listOrgInfo() {
        OrganizationComponent org = constructOrganization();
        System.out.println(String.format("%s共有%d名员工",
                org.getName(), org.getStaffCount()));

        OrganizationComponent subOrg = org.getChild("天津分公司行政部");
        System.out.println(String.format("%s共有%d名员工",
                subOrg.getName(), subOrg.getStaffCount()));
    }
}

运行:

总公司共有238名员工
天津分公司行政部共有99名员工

程序描述的公司和部门结构如下图:

设计模式之组合模式_第2张图片

写在后面

参考文章列表

秒懂设计模式之组合模式(Composite Pattern) 。

你可能感兴趣的:(设计模式,设计模式,组合模式,java,结构型设计模式)