19 组合模式(Composite Pattern)

1 定义

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

2 透明方式和安全方式

两者各有好处,视情况而定选哪种。

  • 透明方式:Compoment抽象类中声明了用来管理子类的方法,包括add(), remove()等,这样继承了该抽象类的类都具有add(), remove()方法。好处:叶节点和枝节点对于外界没有区别,具备一致的行为接口。缺点:Leaf类本身不具备add(), remove()方法的功能,所以实现它是没有意义的。
  • 安全方式:Compoment抽象类中不声明add(), remove(),Leaf类就不用实现这2个方法,而是在Composite中声明用来管理子类对象的方法。好处:不会出现上面的问题。缺点:树叶和树枝类不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

3 适用场景

  • 需求中是体现部分与整体层次的结构时;
  • 希望用户可以忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象时;
    满足以上两点,则应该考虑 使用组合模式。

4 优势

  • 组合模式定义了包含基本对象和组合对象的层次结构。基本对象可以被组合成更复杂的组合对象,这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何使用到基本对象的地方都可以使用组合对象了
  • 让客户可以一致的使用组合结构和单个对象。

5 UML图

在这里插入图片描述

6 例子

6.1 场景

北京总公司下面有很多直属部门和分公司。不管是直属部门还是分公司下面的小部门,只要他们是同一类型的部门,比如都是财务部,就应该有一样的功能职责。公司层次结构图如下:
在这里插入图片描述

6.2 UML图

在这里插入图片描述

6.3 code

Main

public class Main {
    public static void main(String[] args) {
        ConcreteCompany company=new ConcreteCompany("总公司");
        FinanceDepartment financeDepartment=new FinanceDepartment("总公司财务部");
        HRDepartment hrDepartment=new HRDepartment("总公司人力资源部");
        company.add(financeDepartment);
        company.add(hrDepartment);

        //一级分公司
        ConcreteCompany subCmp1=new ConcreteCompany("上海华东分公司");
        FinanceDepartment financeDepartment1=new FinanceDepartment("上海华东分公司财务部");
        HRDepartment hrDepartment1=new HRDepartment("上海华东分公司人力资源部");
        subCmp1.add(financeDepartment1);
        subCmp1.add(hrDepartment1);
        company.add(subCmp1);

        //二级分公司
        ConcreteCompany subCmp2=new ConcreteCompany("南京办事处");
        FinanceDepartment financeDepartment2=new FinanceDepartment("南京办事处财务部");
        HRDepartment hrDepartment2=new HRDepartment("南京办事处人力资源部");
        subCmp2.add(financeDepartment2);
        subCmp2.add(hrDepartment2);
        subCmp1.add(subCmp2);

        //二级分公司
        ConcreteCompany subCmp3=new ConcreteCompany("杭州办事处");
        FinanceDepartment financeDepartment3=new FinanceDepartment("杭州办事处财务部");
        HRDepartment hrDepartment3=new HRDepartment("杭州办事处人力资源部");
        subCmp3.add(financeDepartment3);
        subCmp3.add(hrDepartment3);
        subCmp1.add(subCmp3);

        //展示公司层级结构
        System.out.println("公司层级结构如下:");
        company.display(1);

        //展示各个部门职责
        System.out.println("各个部门职责如下:");
        company.lineOfDuty();
    }
}

Company

public abstract class Company {
    protected String name;

    public Company(String name){
        //注意这里要写上this哦,不然就成了:参数=参数,类属性并未赋值,依然是null
        this.name=name;
    }

    public abstract void add(Company c);//增加
    public abstract void remove(Company c);//移除
    public abstract void display(int depth);//显示
    public abstract void lineOfDuty();//履行职责
}

ConcreteCompany

public class ConcreteCompany extends Company {
    private List<Company> children=new ArrayList<>();

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

    @Override
    public void add(Company c) {
        children.add(c);
    }

    @Override
    public void remove(Company c) {
        children.remove(c);
    }

    @Override
    public void display(int depth) {
        StringBuilder sb=new StringBuilder();
        while (depth--!=0){
            sb.append("-");
        }
        System.out.println(sb.toString()+name);
        for (Company c:children) {
            c.display(depth+2);
        }
    }

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

HRDepartment

//人力资源部门
public class HRDepartment extends Company {

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

    @Override
    public void add(Company c) {
    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void display(int depth) {
        StringBuilder sb=new StringBuilder();
        while (depth--!=0){
            sb.append("-");
        }
        System.out.println(sb.toString()+name);
    }

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

FinanceDepartment

//财务部门
public class FinanceDepartment extends Company {

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

    @Override
    public void add(Company c) {
    }

    @Override
    public void remove(Company c) {

    }

    @Override
    public void display(int depth) {
        StringBuilder sb=new StringBuilder();
        while (depth--!=0){
            sb.append("-");
        }
        System.out.println(sb.toString()+name);
    }

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

参考
https://blog.csdn.net/caoxiaohong1005/article/details/79155028

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值