浅谈Java设计模式——组合模式(Composite)

一、概述

        将对象组合成树形结构以表示"部分-整体"的层次结构。"Composite使得用户对单个对象和组合对象的使用具有一致性。它定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。虽然组合模式能够清晰地定义分层次的复杂对象,也使得增加新构件也更容易,但是这样就导致了系统的设计变得更加抽象,如果系统的业务规则比较复杂的话,使用组合模式就有一定的挑战了。

二、使用场景

1.你想表示对象的部分-整体层次结构。

2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

三、参与者

1.Component 为组合中的对象声明接口。 在适当的情况下,实现所有类共有接口的缺省行为。 声明一个接口用于访问和管理Component                         的子组件。 (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。

2.Leaf 在组合中表示叶节点对象,叶节点没有子节点。 在组合中定义节点对象的行为。 

3.Composite 定义有子部件的那些部件的行为。 存储子部件。 在Component接口中实现与子部件有关的操作。 

4.Client 通过Component接口操纵组合部件的对象。

四、类图

五、代码示例

1.Component

/**
 * Component
 * @author zhipeng_Tong
 */
public abstract class Company {
    protected String name;

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

    public abstract void add(Company company);  // 添加
    public abstract void remove(Company company);   // 删除
    public abstract void display(int depth);    // 显示
    public abstract void lineOfDuty();  // 履行职责
}

2.Leaf

/**
 * Leaf
 * @author zhipeng_Tong
 */
public class FinanceDepartment extends Company {
    public FinanceDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void remove(Company company) {

    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++)
            System.out.print("-");
        System.out.println(name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(String.format("%s 公司财务收支管理", name));
    }
}

/**
 * Leap
 * @author zhipeng_Tong
 */
public class HRDepartment extends Company {
    public HRDepartment(String name) {
        super(name);
    }

    @Override
    public void add(Company company) {

    }

    @Override
    public void remove(Company company) {

    }

    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++)
            System.out.print("-");
        System.out.println(name);
    }

    @Override
    public void lineOfDuty() {
        System.out.println(String.format("%s 员工招聘培训管理", name));
    }
}

3.Composite

/**
 * Composite
 * @author zhipeng_Tong
 */
public class ConcreteCompany extends Company{
    private ArrayList<Company> companies = new ArrayList<>();

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

    @Override
    public void add(Company company) {
        companies.add(company);
    }

    @Override
    public void remove(Company company) {
        companies.remove(companies);
    }

    @Override
    public void display(int depth) {
        toDisplay(depth);

        for (Company c : companies)
            c.display(depth + 2);
    }

    private void toDisplay(int depth) {
        for (int i = 0; i < depth; i++)
            System.out.print("-");
        System.out.println(name);
    }

    @Override
    public void lineOfDuty() {
        for (Company c : companies)
            c.lineOfDuty();
    }
}

4.Client 通过Component接口操纵组合部件的对象。

public class Client {
    public static void main(String[] args) {
        ConcreteCompany root = new ConcreteCompany("北京总公司");
        root.add(new HRDepartment("总公司人力资源部"));
        root.add(new FinanceDepartment("总公司财务部"));

        ConcreteCompany company = new ConcreteCompany("上海华东分公司");
        company.add(new HRDepartment("上海华东分公司人力资源部"));
        company.add(new FinanceDepartment("上海华东分公司人财务部"));
        root.add(company);

        ConcreteCompany company2 = new ConcreteCompany("南京办事处");
        company2.add(new HRDepartment("南京办事处人力资源部"));
        company2.add(new FinanceDepartment("南京办事处人财务部"));
        company.add(company2);

        ConcreteCompany company3 = new ConcreteCompany("吉林东北分公司");
        company3.add(new HRDepartment("吉林东北分公司人力资源部"));
        company3.add(new FinanceDepartment("吉林东北分公司人财务部"));
        root.add(company3);

        ConcreteCompany company4 = new ConcreteCompany("长春办事处");
        company4.add(new HRDepartment("长春办事处人力资源部"));
        company4.add(new FinanceDepartment("长春办事处人财务部"));
        company3.add(company4);

        System.out.println("结构图:");
        root.display(1);

        System.out.println("职责:");
        root.lineOfDuty();
    }
}

运行结果

结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----上海华东分公司人力资源部
-----上海华东分公司人财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处人财务部
---吉林东北分公司
-----吉林东北分公司人力资源部
-----吉林东北分公司人财务部
-----长春办事处
-------长春办事处人力资源部
-------长春办事处人财务部
职责:
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
上海华东分公司人力资源部 员工招聘培训管理
上海华东分公司人财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处人财务部 公司财务收支管理
吉林东北分公司人力资源部 员工招聘培训管理
吉林东北分公司人财务部 公司财务收支管理
长春办事处人力资源部 员工招聘培训管理
长春办事处人财务部 公司财务收支管理

 

posted @ 2018-11-15 19:42  小情绪Ango  阅读(165)  评论(0编辑  收藏  举报