设计模式之十一组合模式(结构型)

        前言:

        组合模式亦称: 对象树、Object Tree、Composite,是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们。组合模式解决这样的问题,当我们的要处理的对象可以生成一颗树形结构,而 我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑 它是节点还是叶子。

       --GoF 的《设计模式》定义:将一组对象组织(Compose)成树形结构,以表示一种“部分 - 整体”的层次结构。组合让客户端可以统一单个对象和组合对象的处理逻辑。

        

目录

一、结构

二、代码实现

三、组合模式在HashMap中的应用

四、组合模式适合应用场景

五、组合模式优缺点

六、与其他模式的关系


 

一、结构

二、代码实现

统计大学、各学院、各系的学生

/**
 * @Description: 组织抽象类
 *
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public abstract class OrganizationComponent {
    private String name; // 名字
    private String des; // 说明
    private int num; // 学生人数

    protected  void add(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    protected  void remove(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    //构造器
    public OrganizationComponent(String name, String des) {
        super();
        this.name = name;
        this.des = des;
    }

    public String getName() {
        return name;
    }

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

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    // 方法print, 做成抽象的, 子类都需要实现
    protected abstract void print();

}


/**
 * @Description: 学院
 *
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public class College extends OrganizationComponent{
    // List 中 存放的Department
    List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();

    // 构造器
    public College(String name, String des) {
        super(name, des);
        // TODO Auto-generated constructor stub
    }

    // 重写add
    @Override
    protected void add(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        //  将来实际业务中,Colleage 的 add 和  University add 不一定完全一样
        organizationComponents.add(organizationComponent);
    }

    // 重写remove
    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        organizationComponents.remove(organizationComponent);
    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return super.getName();
    }

    @Override
    public String getDes() {
        // TODO Auto-generated method stub
        return super.getDes();
    }

    @Override
    public int getNum() {
        // TODO Auto-generated method stub
        int num = 0;
        for (OrganizationComponent organizationComponent : organizationComponents) {
            num += organizationComponent.getNum();
        }
        return num;
    }

    // print方法,就是输出University 包含的学院
    @Override
    protected void print() {
        // TODO Auto-generated method stub
        System.out.println();
        System.out.println("--------------" + getName() + "--------------人数:" + getNum());
        System.out.println();
        //遍历 organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }

}


/**
 * @Description: 系
 *
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public class Department extends OrganizationComponent{
    List<OrganizationComponent> organizationComponentList = new ArrayList<>();

    public Department(String name, String des) {
        super(name, des);
        // TODO Auto-generated constructor stub
    }

    // 重写add
    @Override
    protected void add(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        organizationComponentList.add(organizationComponent);
    }

    // 重写remove
    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        organizationComponentList.remove(organizationComponent);
    }



    //add , remove 就不用写了,因为他是叶子节点

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return super.getName();
    }

    @Override
    public String getDes() {
        // TODO Auto-generated method stub
        return super.getDes();
    }

    @Override
    public int getNum() {
        // TODO Auto-generated method stub
        return organizationComponentList.size();
    }


    @Override
    protected void print() {
        // TODO Auto-generated method stub
        System.out.println("--------------" + getName() + "--------------人数:" + getNum());
        for (OrganizationComponent organizationComponent : organizationComponentList) {
            organizationComponent.print();
        }

    }

}



/**
 * @Description: 学生
 *
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public class Student extends OrganizationComponent{
    //没有集合

    public Student(String name, String des) {
        super(name, des);
        // TODO Auto-generated constructor stub
    }


    //add , remove 就不用写了,因为他是叶子节点

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return super.getName();
    }

    @Override
    public String getDes() {
        // TODO Auto-generated method stub
        return super.getDes();
    }

    @Override
    public int getNum() {
        // TODO Auto-generated method stub
        return super.getNum();
    }

    @Override
    protected void print() {
        // TODO Auto-generated method stub
        System.out.println(getName());
    }

}


/**
 * @Description: 大学(Composite)
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public class University extends OrganizationComponent{
    List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();

    // 构造器
    public University(String name, String des) {
        super(name, des);
        // TODO Auto-generated constructor stub
    }

    // 重写add
    @Override
    protected void add(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        organizationComponents.add(organizationComponent);
    }

    // 重写remove
    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        // TODO Auto-generated method stub
        organizationComponents.remove(organizationComponent);
    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return super.getName();
    }

    @Override
    public String getDes() {
        // TODO Auto-generated method stub
        return super.getDes();
    }

    @Override
    public int getNum() {
        // TODO Auto-generated method stub
        int num = 0;
        for (OrganizationComponent organizationComponent : organizationComponents) {
            num += organizationComponent.getNum();
        }
        return num;
    }


    // print方法,就是输出University 包含的学院
    @Override
    protected void print() {
        // TODO Auto-generated method stub
        System.out.println("--------------" + getName() + "--------------人数:" + getNum());
        //遍历 organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }
}
/**
 * @Description: TODO
 * @Author HJW
 * @Date 2021/4/22
 * @Version V1.0
 **/
public class Client {
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //从大到小创建对象 学校
        OrganizationComponent university = new University("清华大学", " 中国顶级大学 ");

        //创建 学院
        OrganizationComponent computerCollege = new College("计算机学院", " 计算机学院 ");
        OrganizationComponent infoEngineercollege = new College("信息工程学院", " 信息工程学院 ");

        // 创建系
        Department soft = new Department("软件工程", " 软件工程不错 ");
        Department network = new Department("网络工程", " 网络工程不错 ");
        Department computer = new Department("计算机科学与技术", " 计算机科学与技术是老牌的专业 ");
        Department communication  = new Department("通信工程", " 通信工程不好学 ");
        Department information = new Department("信息工程", " 信息工程好学 ");

        soft.add(new Student("张三", "三好学生"));
        soft.add(new Student("李四", "三好学生"));
        network.add(new Student("王五", "三好学生"));
        network.add(new Student("赵六", "三好学生"));
        network.add(new Student("田七", "三好学生"));
        computer.add(new Student("黑八", "三好学生"));
        communication.add(new Student("冯九", "三好学生"));
        communication.add(new Student("黄二", "三好学生"));
        information.add(new Student("范一", "三好学生"));
        information.add(new Student("袁零", "三好学生"));


        //创建各个学院下面的系(专业)
        computerCollege.add(soft);
        computerCollege.add(network);
        computerCollege.add(computer);
        infoEngineercollege.add(communication);
        infoEngineercollege.add(information);

        //将学院加入到 学校
        university.add(computerCollege);
        university.add(infoEngineercollege);

        university.print();
//        infoEngineercollege.print();
    }
}

三、组合模式在HashMap中的应用

Java 的集合类 -HashMap 就使用了组合模式
public class HashMapComp {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Map<Integer,String> hashMap=new HashMap<Integer,String>();
        hashMap.put(0, "冠军");//直接存放叶子节点
        Map<Integer,String> map=new HashMap<Integer,String>();
        map.put(1, "亚军");
        map.put(2, "季军"); 
        hashMap.putAll(map);
        System.out.println(hashMap);
    }
}
public interface Map<K,V> {
    //add, remover..
}
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable,Serializable { }
static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;
 }

四、组合模式适合应用场景

  •  如果需要实现树状对象结构, 可以使用组合模式。

      组合模式提供了两种共享公共接口的基本元素类型: 简单叶节点和复杂容器。 容器中可以包含叶节点和其他容器。 这使得你可以构建树状嵌套递归对象结构。

  •  如果希望客户端代码以相同方式处理简单和复杂元素, 可以使用该模式。

        组合模式中定义的所有元素共用同一个接口。 在这一接口的帮助下, 客户端不必在意其所使用的对象的具体类。

 

五、组合模式优缺点

  •  可以利用多态和递归机制更方便地使用复杂树结构。
  •  开闭原则。 无需更改现有代码, 你就可以在应用中添加新元素, 使其成为对象树的一部分。
  •  XXX对于功能差异较大的类, 提供公共接口或许会有困难。 在特定情况下, 需要过度一般化组件接口, 使其变得令人难以理解。

六、与其他模式的关系

  • 桥接模式、 状态模式策略模式 (在某种程度上包括适配器模式) 模式的接口非常相似。 实际上, 它们都基于组合模式——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。

  • 可以在创建复杂组合树时使用生成器模式, 因为这可使其构造步骤以递归的方式运行。

  • 责任链模式通常和组合模式结合使用。 在这种情况下, 叶组件接收到请求后, 可以将请求沿包含全体父组件的链一直传递至对象树的底部。

  • 你可以使用迭代器模式来遍历组合树。

  • 你可以使用访问者模式对整个组合树执行操作。

  • 你可以使用享元模式实现组合树的共享叶节点以节省内存。

  • 组合装饰模式的结构图很相似, 因为两者都依赖递归组合来组织无限数量的对象。

    装饰类似于组合, 但其只有一个子组件。 此外还有一个明显不同: 装饰为被封装对象添加了额外的职责, 组合仅对其子节点的结果进行了 “求和”。

    但是, 模式也可以相互合作: 你可以使用装饰来扩展组合树中特定对象的行为。

  • 大量使用组合装饰的设计通常可从对于原型模式的使用中获益。 你可以通过该模式来复制复杂结构, 而非从零开始重新构造。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值