组合模式——一致地使用多个对象

目录

一、基础简介

1、定义

2、使用场景

3、优缺点

4、模式结构解析

二、模式实例实现

1、场景

2、Component 是组合中的对象声明接口:抽象公司类

3、Composite 定义有枝节点行为,用来存储子部件:具体公司类

4、Leaf 在组合中表示叶子结点对象,叶子结点没有子结点

5、客户端

6、结果展示


一、基础简介

1、定义

将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

2、使用场景

当需求中是体现部分与整体层次的结构时,同时希望用户可以忽略组合对象与单个对象的不同统一使用组合结构中的所有对象时,就考虑使用该模式

3、优缺点

优点: 1、高层模块调用简单。 2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

4、模式结构解析

该模式有三个角色:Component、Leaf、Composite,关于角色介绍请看下图:

二、模式实例实现

1、场景

一个大型公司,会有一个“总公司”,多个“分公司”,“分公司”下还会有“办事处”,但相同的是,都会有一些共同的职能部门,比如说“人力资源部”,“财务部”等。

2、Component 是组合中的对象声明接口:抽象公司类

package com.mfc.design.组合模式;

/**
 * @author MouFangCai
 * @date 2019/10/19 16:40
 *
 * Component:组合中的对象申明接口
 */
public abstract class Company {

    private 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();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3、Composite 定义有枝节点行为,用来存储子部件:具体公司类

package com.mfc.design.组合模式;


import java.util.ArrayList;
import java.util.List;

/**
 * @author MouFangCai
 * @date 2019/10/19 16:46
 *
 * Composite:定义有支节点行为,用来存储子部件
 */
public class ConcreteCompany extends Company {

    private List<Company> childrens = new ArrayList<>();

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

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

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

    // 层级展示
    @Override
    public void display(int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(getName());

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

    // 部门职责
    @Override
    public void lineOfDuty() {
        for (Company c : childrens) {
            c.lineOfDuty();
        }
    }
}

4、Leaf 在组合中表示叶子结点对象,叶子结点没有子结点

package com.mfc.design.组合模式;

/**
 * @author MouFangCai
 * @date 2019/10/19 17:06
 *
 * Leaf:在组合中表示叶节点对象,叶节点没有子节点
 */
public class HR_Department extends Company {

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

    // 由于“叶子”没有再增加分支和树叶的能力,所以add()和remove()实现是没有意义的
    @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(getName());
    }

    @Override
    public void lineOfDuty() {
        System.out.println(getName() + ": 负责招聘");
    }
}
package com.mfc.design.组合模式;

/**
 * @author MouFangCai
 * @date 2019/10/19 17:16
 */
public class Finance_Department extends Company {
    public Finance_Department(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(getName());
    }

    @Override
    public void lineOfDuty() {
        System.out.println(getName() + ":负责财务结算");
    }
}

5、客户端

package com.mfc.design.组合模式;

/**
 * @author MouFangCai
 * @date 2019/10/19 17:17
 */
public class Client_Component {

    public static void main(String[] args) {
        ConcreteCompany root = new ConcreteCompany("mfc总公司");
        root.add(new HR_Department("总公司-HR部"));
        root.add(new Finance_Department("总公司-财务部"));
        // 一级分公司
        ConcreteCompany subComp01 = new ConcreteCompany("01分公司");
        subComp01.add(new HR_Department("01分公司-HR部"));
        subComp01.add(new Finance_Department("01分公司-财务部"));
        root.add(subComp01);
        // 二级办事处
        ConcreteCompany subComp02 = new ConcreteCompany("01办事处");
        subComp02.add(new HR_Department("01办事处-HR部"));
        subComp02.add(new Finance_Department("01办事处-财务部"));
        subComp01.add(subComp02);

        System.out.println("\n公司架构图:");
        root.display(1);

        System.out.println("\n部门职责详情:");
        root.lineOfDuty();

    }
}

6、结果展示

公司架构图:
-mfc总公司
---总公司-HR部
---总公司-财务部
---01分公司
-----01分公司-HR部
-----01分公司-财务部
-----01办事处
-------01办事处-HR部
-------01办事处-财务部

部门职责详情:
总公司-HR部: 负责招聘
总公司-财务部:负责财务结算
01分公司-HR部: 负责招聘
01分公司-财务部:负责财务结算
01办事处-HR部: 负责招聘
01办事处-财务部:负责财务结算

Process finished with exit code 0

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值