相关推荐recommended
笨蛋学设计模式结构型模式-组合模式【12】
作者:mmseoamin日期:2024-01-19

结构型模式-组合模式

    • 7.6组合模式
      • 7.6.1概念
      • 7.6.2场景
      • 7.6.3优势 / 劣势
      • 7.6.4组合模式可分为
      • 7.6.5组合模式
      • 7.6.6实战
        • 7.6.6.1题目描述
        • 7.6.6.2输入描述
        • 7.6.6.3输出描述
        • 7.6.6.4代码
        • 7.6.7总结
        • 组合模式

          7.6组合模式

          7.6.1概念

          ​ 组合模式通过将对象组合成树状结构来表示 部分-整体的层次关系,从而让客户端能够以同样的方式处理单个对象和对象组合,在使用中将他们视为同一类型的对象。

          7.6.2场景

          ​ 在文件系统中,比如目录和文件就形成了一个树形结构,目录可以包含文件以及子目录,而子目录同样的也可以包含文件以及子目录的子目录。

          7.6.3优势 / 劣势

          • 一致性:客户端可以统一的处理单个对象和对象的组合,简化了客户端的代码
          • 动态性:组合模式支持动态地添加或删除子对象,使得树形结构的构建更加灵活
            • 复杂性:由于树形机构的嵌套特性,可能会增加代码的复杂性
            • 深度限制:若组合模式的树形结构的深度过大,可能会导致性能问题

              7.6.4组合模式可分为

              • 组件Component:组合模式的根节点,定义组合中所有对象的通用接口,可以是抽象类或接口。该类中定义了子类的共性内容
              • 叶子Leaf:实现了Component接口的叶子节点,表示组合中的叶子对象,叶子节点没有子节点
              • 合成Composite:作用是存储子部件,并且在Composite中实现了对子部件的相关操作,比如添加、删除、获取子组件等

                7.6.5组合模式

                package com.technologystatck.designpattern.mode.combination;
                import java.util.ArrayList;
                import java.util.List;
                public class Combination {
                    public static void main(String[] args) {
                        //创建叶子节点
                        Leaf leaf = new Leaf();
                        //创建组合节点,并添加叶子节点
                        Composite composite = new Composite();
                        composite.add(leaf);
                        //统一调用
                        composite.operation();
                        System.out.println("----------------------");
                        composite.remove(leaf);
                        composite.operation();
                    }
                }
                //组件接口
                interface Component{
                    void operation();
                }
                //叶子节点
                class Leaf implements Component{
                    @Override
                    public void operation() {
                        System.out.println("Leaf operation");
                    }
                }
                //组合节点
                class Composite implements Component{
                    private List components=new ArrayList<>();
                    public void add(Component component){
                        components.add(component);
                    }
                    public void remove(Component component){
                        components.remove(component);
                    }
                    @Override
                    public void operation() {
                        System.out.println("Composite operation");
                        for(Component component:components){
                            component.operation();
                        }
                    }
                }
                

                7.6.6实战

                7.6.6.1题目描述

                小明所在的公司内部有多个部门,每个部门下可能有不同的子部门或者员工。

                请你设计一个组合模式来管理这些部门和员工,实现对公司组织结构的统一操作。部门和员工都具有一个通用的接口,可以获取他们的名称以及展示公司组织结构。

                7.6.6.2输入描述

                第一行是一个整数 N(1 <= N <= 100),表示后面有 N 行输入。

                接下来的 N 行,每行描述一个部门或员工的信息。部门的信息格式为 D 部门名称,员工的信息格式为 E 员工名称,其中 D 或 E 表示部门或员工。

                7.6.6.3输出描述

                输出公司的组织结构,展示每个部门下的子部门和员工

                7.6.6.4代码
                package com.technologystatck.designpattern.mode.combination;
                import java.util.ArrayList;
                import java.util.List;
                import java.util.Scanner;
                public class Test {
                    public static void main(String[] args) {
                        Scanner scanner = new Scanner(System.in);
                        //先读取公司名称
                        String companyName = scanner.nextLine();
                        //创建公司对象,并设置公司名称,并将公司添加到树枝节点中
                        Company company = new Company(companyName);
                        //读取部门和员工信息
                        int nums = scanner.nextInt();
                        scanner.nextLine();
                        for(int i=0;i
                            String type = scanner.next();
                            //获取名字并去除空格,以便后续添加到组合节点中
                            String name = scanner.nextLine().trim();
                            if("D".equals(type)){
                                //创建部门对象,并添加到组合节点中
                                company.add(new Department(name));
                            }else if("E".equals(type)){
                                //创建员工对象,并添加到组合节点中
                                company.add(new Employee(name));
                            }
                        }
                        //显示公司信息
                        company.display();
                    }
                }
                //组件接口
                interface Components{
                    void display(int depth);
                }
                //部门的叶子节点
                class Department implements Components{
                    //部门名称
                    private String name;
                    //部门下的员工
                    private List children;
                    public Department(String name) {
                        this.name = name;
                        this.children = new ArrayList<>();
                    }
                    //添加员工
                    public void add(Components component){
                        children.add(component);
                    }
                    //删除员工
                    public void remove(Components component){
                        children.remove(component);
                    }
                    @Override
                    public void display(int depth) {
                        StringBuilder indent = new StringBuilder();
                        for(int i = 0;i < depth;i++){
                            //一个空格
                            indent.append(" ");
                        }
                        System.out.println(indent + name);
                        for (Components components : children) {
                            components.display(depth+1);
                        }
                    }
                }
                //员工的叶子节点
                class Employee implements Components{
                    //员工名
                    private String name;
                    public Employee(String name) {
                        this.name = name;
                    }
                    @Override
                    public void display(int depth) {
                        StringBuilder indent = new StringBuilder();
                        for(int i = 0;i < depth;i++){
                            //两个空格,用于缩进显示层级关系
                            indent.append("  ");
                        }
                        System.out.println(indent + name);
                    }
                }
                //树枝节点,也就是组合节点
                class Company{
                    private String name;
                    //部门相当于根节点
                    private Department root;
                    public Company(String name) {
                        this.name = name;
                        this.root = new Department(name);
                    }
                    public void add(Components components){
                        root.add(components);
                    }
                    public void remove(Components components){
                        root.remove(components);
                    }
                    public void display(){
                        System.out.println("Company Structure");
                        //从1开始,以适配指定的缩进格式
                        root.display(0);
                    }
                }
                

                7.6.7总结

                • 组合模式

                • 优点:可以通过组合多个对象形成对象组合,然后再增加新的功能或行为,只需要对组合对象进行操作

                • 总结:是一种通过将对象组合成树形结构,提供了灵活且统一的方式来处理单个对象和对象组合

                • 场景:需要构建具有部分-整体层次结构的场景,比如组织架构管理、文件系统的文件和文件夹组织