组合模式详解

简介:就是树状图结构的多个类

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。

  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。

  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

 

package composite;


import java.security.Provider;
import java.util.ArrayList;
import java.util.List;

//总公司-分公司-部门
public class Make {
    public static void main(String[] args) {
        ConcreteCompany root = new ConcreteCompany("沈阳总公司");
        root.Add(new HRDepartment("总公司人力资源部"));
        root.Add(new FinanceDepartment("总公司财务部"));

        ConcreteCompany anshan = new ConcreteCompany("鞍山分公司");
        root.Add(anshan);
        anshan.Add(new HRDepartment("鞍山分公司人力资源部"));
        anshan.Add(new FinanceDepartment("鞍山分公司财务部"));


        ConcreteCompany fushun = new ConcreteCompany("抚顺分公司");
        root.Add(fushun);
        fushun.Add(new HRDepartment("抚顺分公司人力资源部"));
        fushun.Add(new FinanceDepartment("抚顺分公司财务部"));

        System.out.println("结构图:");
        root.Display(1);
        System.out.println("职责:");
        root.LineOfDuty();

        /**
         * 结构图:
         * -沈阳总公司
         * ---总公司人力资源部
         * ---总公司财务部
         * ---鞍山分公司
         * -----鞍山分公司人力资源部
         * -----鞍山分公司财务部
         * ---抚顺分公司
         * -----抚顺分公司人力资源部
         * -----抚顺分公司财务部
         * 职责:
         * 总公司人力资源部员工招聘培训管理
         * 总公司财务部公司财务收支管理
         * 鞍山分公司人力资源部员工招聘培训管理
         * 鞍山分公司财务部公司财务收支管理
         * 抚顺分公司人力资源部员工招聘培训管理
         * 抚顺分公司财务部公司财务收支管理
         */

    }
}


//抽象公司类
abstract class Company {
    String name;

    public Company(String name) {
        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();//履行职责
}

//公司类 (枝杈)
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) {
        System.out.print("-");
        for(int i = 1; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println(this.name);
        for (Company c:children) {
            c.Display(depth + 2);
        }
    }

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

//部门类 (叶子)
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) {
        for(int i = 1; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println("-" + this.name);
    }

    @Override
    public void LineOfDuty() {
        System.out.println(this.name + "员工招聘培训管理");
    }
}

//部门类 (叶子)
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) {
        for(int i = 1; i < depth; i++) {
            System.out.print("-");
        }
        System.out.println("-" + this.name);
    }

    @Override
    public void LineOfDuty() {
        System.out.println(this.name + "公司财务收支管理");
    }
}

缺点:

组合模式的主要缺点如下:

  • 破坏了“单一职责原则”。

  • 在增加新构件时很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件,使用组合模式时,不能依赖类型系统来施加这些约束,因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。

优点

组合模式的主要优点如下:

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。

  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。

  • 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。

  • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的

适用环境

在以下情况下可以考虑使用组合模式:

  • 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。

  • 在一个使用面向对象语言开发的系统中需要处理一个树形结构。

  • 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

  • 树形结构,但对树形结构的控制却非常简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值