笨蛋学设计模式结构型模式-组合模式【12】

结构型模式-组合模式

7.6组合模式

7.6.1概念

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

7.6.2场景

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

7.6.3优势 / 劣势

  • 一致性:客户端可以统一的处理单个对象和对象的组合,简化了客户端的代码
  • 动态性:组合模式支持动态地添加或删除子对象,使得树形结构的构建更加灵活

  • 复杂性:由于树形机构的嵌套特性,可能会增加代码的复杂性
  • 深度限制:若组合模式的树形结构的深度过大,可能会导致性能问题

7.6.4组合模式可分为

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

7.6.5组合模式

java 复制代码
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<Component> 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代码
java 复制代码
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<nums;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<Components> 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总结

组合模式

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

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

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

相关推荐
reddingtons22 分钟前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐40 分钟前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆2 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin3 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20053 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉3 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国3 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882483 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈4 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_994 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc