结构型模式3.组合模式

结构型模式

  1. 适配器模式(Adapter Pattern)
  2. 桥接模式(Bridge Pattern)
  3. 组合模式(Composite Pattern)
  4. 装饰器模式(Decorator Pattern)
  5. 外观模式(Facade Pattern)
  6. 享元模式(Flyweight Pattern)
  7. 代理模式(Proxy Pattern)

组合模式(Composite Pattern) 是一种结构型设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以统一对待单个对象和对象集合,即把对象当作单一对象来处理,从而简化了操作和使用的复杂性。

核心思想:

组合模式将对象组合成树形结构,并允许客户端通过统一的接口对待单一对象和对象组合。其本质是树形结构中的每个节点可能是单个对象,也可能是对象的组合(集合)。客户端通过同一接口处理这些对象,从而达到简化代码和增强灵活性的目的。

主要角色:

  1. Component(组件):定义了一个接口,声明了基本的操作(如 add()remove()getChild() 等),这使得单个对象和组合对象(即树枝)都能使用相同的操作。
  2. Leaf(叶子节点):表示树的叶子节点(即最基本的对象),没有子节点,实现了组件接口。
  3. Composite(组合节点):表示树的枝节点(即含有子节点的对象),实现了组件接口,并且能管理子组件。组合节点可以添加、删除和获取子组件。

示例:公司组织结构

假设我们有一个公司组织结构,其中有员工(叶子节点)和经理(组合节点),经理可以有下属员工或者其他经理。这种组织结构非常适合使用组合模式来实现。

// 组件接口
public interface Employee {
    void showDetails(); // 显示员工信息
}

// 叶子节点,代表普通员工
public class RegularEmployee implements Employee {
    private String name;
    private String position;

    public RegularEmployee(String name, String position) {
        this.name = name;
        this.position = position;
    }

    @Override
    public void showDetails() {
        System.out.println("姓名: " + name + ", 职位: " + position);
    }
}

import java.util.ArrayList;
import java.util.List;

// 组合节点,代表经理(可以包含员工或其他经理)
public class Manager implements Employee {
    private String name;
    private String position;
    private List<Employee> subordinates; // 下属

    public Manager(String name, String position) {
        this.name = name;
        this.position = position;
        subordinates = new ArrayList<>();
    }

    public void addSubordinate(Employee employee) {
        subordinates.add(employee);
    }

    public void removeSubordinate(Employee employee) {
        subordinates.remove(employee);
    }

    @Override
    public void showDetails() {
        System.out.println("姓名: " + name + ", 职位: " + position);
        System.out.println("下属: ");
        for (Employee e : subordinates) {
            e.showDetails(); // 递归调用
        }
    }
}

public class Client {
    public static void main(String[] args) {
        // 创建叶子节点(普通员工)
        Employee employee1 = new RegularEmployee("张三", "开发工程师");
        Employee employee2 = new RegularEmployee("李四", "设计师");

        // 创建组合节点(经理)
        Manager manager1 = new Manager("王五", "经理");
        Manager manager2 = new Manager("赵六", "高级经理");

        // 经理1有下属员工
        manager1.addSubordinate(employee1);
        manager1.addSubordinate(employee2);

        // 经理2有经理1作为下属
        manager2.addSubordinate(manager1);

        // 展示组织结构
        System.out.println("经理2的详细信息:");
        manager2.showDetails();
    }
}

解释:

  • Employee(组件):定义了一个接口,所有的员工都实现了这个接口,不管是普通员工还是经理。
  • RegularEmployee(叶子节点):普通员工,不能有下属,实现了 Employee 接口。
  • Manager(组合节点):经理有下属员工或者其他经理。它也实现了 Employee 接口,并且能够管理其他员工(包括普通员工和经理)。

在客户端代码中,ManagerRegularEmployee 都通过 Employee 接口处理,使用 showDetails() 方法递归地展示组织结构。无论是单一的普通员工,还是一个包含多个员工和经理的复杂结构,客户端都可以使用相同的接口来处理它们。

装饰器模式 vs 组合模式:

  • 装饰器模式:用来动态地向一个对象添加额外的功能,通常涉及一个对象及其装饰器对象的组合。
  • 组合模式:用来将对象组织成树形结构,表示“部分-整体”的关系,使得客户端可以统一对待单个对象和对象组合。

优缺点:

优点:
  1. 透明性:客户端不需要关心对象的组成细节,所有对象(包括单一对象和组合对象)都通过相同的接口进行操作。
  2. 灵活性:通过递归组合,可以构建出复杂的树形结构,同时提供统一的操作方法。
  3. 简化代码:对于复杂的层级结构,客户端不需要针对每一层次编写单独的处理代码,减少了重复代码。
缺点:
  1. 过度设计:如果对象本身没有复杂的层次结构,使用组合模式可能会显得过于复杂。
  2. 维护困难:在某些场景下,组合模式可能导致代码结构变得非常复杂,特别是当组合对象的层次较深时。

总结:

组合模式通过递归组合的方式,将对象和对象组合统一处理,使得在处理“部分-整体”结构时,客户端代码更加简洁。它适用于具有树形结构的场景,如文件系统、组织结构、菜单结构等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/951140.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

http range 下载大文件分片

摘自&#xff1a;https://www.jianshu.com/p/32c16103715a 上传分片下载也能分 HTTP 协议范围请求允许服务器只发送 HTTP 消息的一部分到客户端。范围请求在传送大的媒体文件&#xff0c;或者与文件下载的断点续传功能搭配使用时非常有用。 检测服务器端是否支持范围请求 假…

解决WordPress出现Fatal error: Uncaught TypeError: ftp_nlist()致命问题

错误背景 WordPress版本&#xff1a;wordpress-6.6.2-zh_CN WooCommerce版本&#xff1a;woocommerce.9.5.1 WordPress在安装了WooCommerce插件后&#xff0c;安装的过程中没有问题&#xff0c;在安装完成后提示&#xff1a; 此站点遇到了致命错误&#xff0c;请查看您站点管理…

用户使用LLM模型都在干什么?

Anthropic 对用户与 Claude 3.5 Sonnet 的大量匿名对话展开分析&#xff0c;主要发现及相关情况如下&#xff1a; 使用用途分布 软件开发主导&#xff1a;在各类使用场景中&#xff0c;软件开发占比最高&#xff0c;其中编码占 Claude 对话的 15% - 25%&#xff0c;网页和移动应…

【巨实用】Git客户端基本操作

本文主要分享Git的一些基本常规操作&#xff0c;手把手教你如何配置~ ● 一个文件夹中初始化Git git init ● 为了方便以后提交代码需要对git进行配置&#xff08;第一次使用或者需求变更的时候&#xff09;&#xff0c;告诉git未来是谁在提交代码 git config --global user.na…

腾讯云AI代码助手编程挑战赛:自动生成漂亮的网页

在当今数字化时代&#xff0c;网页设计和开发已经成为一项至关重要的技能。在当今时代&#xff0c;借助AI的力量&#xff0c;这部分工作变得简单。本文借助腾讯云AI代码助手——“自动生成需要的网页”。本文将详细介绍如何利用AI代码助手生成网页素材&#xff0c;帮助你轻松打…

多台PC共用同一套鼠标键盘

当环境中有多个桌面 pc 需要操作的时候&#xff0c;在 多台 pc 之间切换会造成很多的不方便 可以通过远程进行连接&#xff0c;但是有一个更好的方案是让多台机器之间共用同一套键盘鼠标 常用的解决方案 synergy 和 sharemouse&#xff0c;通过移动光标在不同的 pc 间切换 s…

UOS系统mysql服务安装

UOS系统mysql服务安装 背景 1、安装环境&#xff1a;kvm虚拟机2、运行环境&#xff1a;uos server-1060e3、架构&#xff1a;x864、安装mysql版本&#xff1a;mysql-5.71、安装准备 # Mysql官网 https://downloads.mysql.com/archives/community/ # 下载安装包 wget -i -c …

Binlog实现MySQL主从同步

主从复制原理 ● Master 数据库只要发生变化&#xff0c;立马记录到Binary log 日志文件中 ● Slave数据库启动一个I/O thread连接Master数据库&#xff0c;请求Master变化的二进制日志 ● Slave I/O获取到的二进制日志&#xff0c;保存到自己的Relay log 日志文件中。 ● Sla…

matlab离线安装硬件支持包

MATLAB 硬件支持包离线安装 本文章提供matlab硬件支持包离线安装教程&#xff0c;因为我的matlab安装的某种原因&#xff08;破解&#xff09;&#xff0c;不支持硬件支持包的安装&#xff0c;相信也有很多相同情况的朋友&#xff0c;所以记录一下我是如何离线安装的&#xff…

C#进阶-在Ubuntu上部署ASP.NET Core Web API应用

随着云计算和容器化技术的普及&#xff0c;Linux 服务器已成为部署 Web 应用程序的主流平台之一。ASP.NET Core 作为一个跨平台、高性能的框架&#xff0c;非常适合在 Linux 环境中运行。本篇博客将详细介绍如何在 Linux 服务器上部署 ASP.NET Core Web API 应用&#xff0c;包…

从光子到图像——相机如何捕获世界?

引言 你是否想过为何我们按一下相机快门就可以将眼前广袤多彩的世界显示于一个小小的相机屏幕上&#xff1f;本期推文中将带着大家重现从光子转换为电子、电子转换为图像中数字驱动值的整个流程。 ▲人们通过相机捕获眼前的场景 从光子到电子的转换 光线首先通过光学镜头进入相…

C# 或 .NetCore 如何使用 NPOI 导出图片到 Excel 文件

今天在本文中&#xff0c;我们将尝试使用NPOI库将图像插入到 Excel 文件的特定位置。请将以下逻辑添加到您的写作方法中&#xff0c;在 Excel 文件中添加图像&#xff08;JPEG、PNG&#xff09;,我已经有一个示例 jpeg 文件 - Read-write-excel-npoi.jpg &#xff0c;我们将尝试…

OpenCV实现基于拉普拉斯算子的浮雕特效

图像浮雕效果的实现原理主要基于图像处理技术&#xff0c;特别是利用图像中像素之间的灰度差异来模拟立体感。以下是对该原理的详细解释&#xff1a; 一、浮雕效果的基本概念 浮雕是把所要呈现的图像突起于材质表面&#xff0c;根据凹凸的程度不同从而形成三维的立体感。在计…

前端用json-server来Mock后端返回的数据处理

<html><body><div class"login-container"><h2>登录</h2><div class"login-form"><div class"form-group"><input type"text" id"username" placeholder"请输入用户名&q…

【xLua】xLua-master签名、加密Lua文件

GitHub - Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. 如果你想在项目工程上操作&#xff0c;又发现项目工程并没导入Tools&#xff0c;可以从xLua-master工程拷贝到项目工程Assets…

Unity学习笔记(六)使用状态机重构角色移动、跳跃、冲刺

前言 本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记 整体状态框架(简化) Player 是操作对象的类&#xff1a; 继承了 MonoBehaviour 用于定义游戏对象的行为&#xff0c;每个挂载在 Unity 游戏对象上的脚本都需要继承自 MonoBehaviour&#x…

AIDD-人工智能药物设计-AlphaFold系列:全面回顾AF1-3的关键研究成果及其对科学界的影响

AlphaFold系列&#xff1a;全面回顾AF1-3的关键研究成果及其对科学界的影响 本文章将围绕 AlphaFold 系列模型在蛋白质结构预测领域的前沿研究展开&#xff0c;重点介绍 AlphaFold1、AlphaFold2 与 AlphaFold3 的关键研究成果&#xff0c;以及它们对科学界和制药工业的深远影响…

Pandas-RFM会员价值度模型

文章目录 一. 会员价值度模型介绍二. RFM计算与显示1. 背景2. 技术点3. 数据4. 代码① 导入模块② 读取数据③ 数据预处理Ⅰ. 数据清洗, 即: 删除缺失值, 去掉异常值.Ⅱ. 查看清洗后的数据Ⅲ. 把前四年的数据, 拼接到一起 ④ 计算RFM的原始值⑤ 确定RFM划分区间⑥ RFM计算过程⑦…

Git 入门指南:如何高效管理你的代码库

文章目录 Git 的介绍安装 Git创建仓库Git 三板斧addcommitpush 冲突问题常用 Git 指令 Git 的介绍 Git 是一个分布式版本控制系统&#xff0c;用于跟踪文件的变化并支持团队协作开发。最初由 Linus Torvalds&#xff08;Linux 操作系统的创始人&#xff09;开发&#xff0c;Gi…

execl条件比较两个sheet每个单元格的值

1.把对比的sheet复制到对比文件中 2.选择首个单元格 3.新建规则 4.选择公式 5.编写公式 A3<>Sheet1!A36.选择差异颜色 7.选择应用范围 $1:$655368.选择应用范围