设计模式之组合模式

1.组合模式的概念:

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

2.组合模式的结构图

3.练习的例子

抽象公司类(结构图当中的Component):

/**
 * 组合模式 抽象公司类
 */
@Data
abstract class Company {

    private String name;


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

    /**
     * 增加节点的方法
     * @param company
     */
    public abstract void add(Company company);

    /**
     * 移除节点的方法
     * @param company
     */
    public abstract void remove(Company company);

    /**
     * 展现树形结构
     */
    public abstract void display(int path);

    /**
     * 公司中的各个部门履行职责
     *
     */
    public abstract void lineOfDuty();

    /**
     * 为了展现层级结构而做的方法
     * @param path
     * @return
     */
    protected String getStr(int path) {
        String str = "";
        for (int i = 0; i <path ; i++) {
            str += "-";
        }
        return str;
    }
}

具体公司类(结构图当中的Compsite):

/**
 * 具体公司类 (树枝节点)
 */
public class ConcreteCompany extends Company {
    //定义一个保存树枝节点 树叶节点的聚集
    private List<Company> arrayList = new ArrayList();

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

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

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

    /**
     * 遍历树
     * @param path
     */
    @Override
    public void display(int path) {
        System.out.println(getStr(path) + getName());
        for (Company company:arrayList ) {
            company.display(path + 2);
        }
    }

    /**
     * 让公司的树叶节(各个办事处)点履行职责
     */
    @Override
    public void lineOfDuty() {
        for (Company company:arrayList ) {
            company.lineOfDuty();
        }
    }
}

具体公司的人力资源部(结构图当中的leaf):

/**
 * 公司的人力资源部(树叶节点)
 */
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 path) {
        System.out.println(getStr(path) + getName());
    }

    @Override
    public void lineOfDuty() {
        System.out.println(getName() + ",招聘新员工!");
    }
}

具体公司的财政部(结构图当中的leaf):

/**
 * 财政部(树叶节点)
 */
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 path) {
        System.out.println(getStr(path) + getName());
    }

    @Override
    public void lineOfDuty() {
        System.out.println(getName() + ",管理公司财政收支!");
    }
}

测试类:

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


        Company company1 = new ConcreteCompany("上海分公司");
        company1.add(new HRDepartment("上海分公司人力资源部"));
        company1.add(new FinanceDepartment("上海分公司财政部"));
        root.add(company1);

        Company company2 = new ConcreteCompany("南京办事处");
        company2.add(new HRDepartment("南京办事处人力资源部"));
        company2.add(new FinanceDepartment("南京办事处出财政部"));
        company1.add(company2);

        Company company3 = new ConcreteCompany("杭州办事处");
        company3.add(new HRDepartment("杭州办事处人力资源部"));
        company3.add(new FinanceDepartment("杭州办事处出财政部"));
        company1.add(company3);

        //打印树的层级结构
        root.display(1);

        System.out.println();

        //各个部门履行职责
        root.lineOfDuty();

    }
}

控制台:

4.例子的结构图

 5.总结

组合方式有两种 上面的示例叫做  “透明模式” 操作子节点的方法声明在抽象的父类当中

  • 问题:叶节点并不具备那些功能,所以实现是没有意义的
  • 好处:叶节点和枝节点对于外界没有区别,他们具备完全一致的行为和接口

另外一种叫做“安全方式”,操作子节点的方法声明在Compsite类当中

  • 问题:由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。
  • 好处:这样叶节点就不用去实现那些无意义的方法了,避免了冗余

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

组合模式的好处:组合模式让用户可以一致的使用组合结构和单个对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值