浅谈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();
    }
}

运行结果

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

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值