设计模式: 结构型之组合模式(6)

组合模式概述

  • 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示“部分-整体”的层次结构
  • 组合模式使得客户端对单个对象和复合对象的使用具有一致性
  • 在 TypeScript 中,组合模式通常涉及到一个接口(或抽象类),它定义了用于操作组件的方法
  • 然后,有两个具体的类实现这个接口
    • 一个是叶子节点类,它表示树形结构中的基本对象
    • 另一个是组合类,它表示包含其他组件的复合对象

组合模式示例

// 定义组件接口  
interface Component {  operation(): void;  add(component: Component): void;  remove(component: Component): void;  getChild(index: number): Component;  
}  // 叶子节点类  
class Leaf implements Component {  private name: string;  constructor(name: string) {  this.name = name;  }  operation(): void {  console.log(`Leaf operation: ${this.name}`);  }  add(component: Component): void {  throw new Error("Leaf cannot add components");  }  remove(component: Component): void {  throw new Error("Leaf cannot remove components");  }  getChild(index: number): Component {  throw new Error("Leaf has no children");  }  
}  // 组合类  
class Composite implements Component {  private children: Component[] = [];  operation(): void {  console.log("Composite operation");  for (const child of this.children) {  child.operation();  }  }  add(component: Component): void {  this.children.push(component);  }  remove(component: Component): void {  const index = this.children.indexOf(component);  if (index !== -1) {  this.children.splice(index, 1);  }  }  getChild(index: number): Component {  if (index < 0 || index >= this.children.length) {  throw new Error("Index out of range");  }  return this.children[index];  }  
}  // 使用示例  
const composite = new Composite();  
const leaf1 = new Leaf("Leaf 1");  
const leaf2 = new Leaf("Leaf 2");  
composite.add(leaf1);  
composite.add(leaf2);  
composite.operation(); // 输出: Composite operation, Leaf operation: Leaf 1, Leaf operation: Leaf 2
  • 这里定义了一个接口:Component
  • 使用 Leaf 和 Composite 继承 Component
    • Leaf 类实现了 Component 接口,表示叶子节点,它只包含 operation 方法的实现,其他方法都抛出了错误,因为叶子节点不应该有子节点
    • Composite 类也实现了 Component 接口,表示复合节点,它包含了所有方法的实现,包括操作自身和子节点的方法
  • 最后,我们创建了一个 Composite 实例作为根节点,并向其中添加了两个 Leaf 实例作为子节点,然后调用了 operation 方法来演示组合模式的使用

组合模式的应用

  • 组合模式(Composite Pattern)的应用场景主要体现在那些需要表示对象的部分-整体层次结构
  • 并且希望客户端能以相同方式处理单个对象和对象集合的情况
  • 以下是组合模式的一些典型应用领域

1 ) 文件系统

  • 在文件系统中,目录(folders)和文件(files)可以构成一个层级结构
  • 目录可以包含子目录和文件,而文件则是叶子节点
  • 组合模式允许我们以统一的方式来操作文件和目录,例如创建、删除、移动、列出内容等,无论处理的是单个文件还是整个目录结构

2 ) GUI 组件库

  • 在图形用户界面(GUI)开发中,窗口、面板、按钮等控件可以嵌套组成复杂的界面结构
  • 组合模式使得我们可以一致地处理顶级容器组件(如窗口)和子组件(如按钮)
  • 无论是添加、删除、布局或绘制组件,都可以采用同样的接口进行

3 ) 组织结构

  • 在企业管理系统中,组织架构通常是一个分层结构,包括部门、小组和个人员工
  • 使用组合模式可以方便地管理和展示这种层级关系,如查询某个员工的所有上级领导、计算某个部门的总人数、调整组织架构等

4 ) HTML DOM 树

  • 浏览器中的 HTML 文档对象模型(DOM)就是一个典型的组合模式实例。
  • DOM 节点可以是元素节点(如

    ),也可以是文本节点,它们共同构成了一个树形结构。

  • 开发者可以以统一的方式遍历、修改或操作 DOM 树中的任何节点,不论它是叶节点(文本节点)还是复合节点(元素节点及其子节点)

5 ) 游戏开发

  • 在游戏引擎中,场景可能包含多个实体,这些实体可能是独立的游戏对象,也可能是包含多个子对象的复杂对象,如角色由身体、头部、四肢等部件组成
  • 组合模式允许开发者以一致的方式来处理单个对象的动作、渲染和其他功能,无论对象是否包含子对象

6 ) XML/JSON 数据解析

  • 解析 XML 或 JSON 数据时,文档结构通常包含嵌套的元素或对象
  • 组合模式可以用来构建解析器,使其能以同样的方式处理简单的元素和含有子元素的复杂元素

7 ) 总结来说

  • 组合模式的应用在于它帮助我们构造和管理树形结构的数据和对象,简化了处理复杂层次结构的逻辑
  • 并且降低了客户端代码与结构内部细节之间的耦合度

组合模式不适用场景

  • 组合模式虽然是一种强大的设计模式,但并非所有场景都适合使用它
  • 以下是一些组合模式不适合应用的地方

1 ) 简单的对象结构

  • 如果应用程序中的对象结构相对简单,且不需要复杂的组合和嵌套,那么使用组合模式可能会增加不必要的复杂性
  • 在这种情况下,使用简单的面向对象技术可能就足够了

2 ) 对性能有严格要求

  • 组合模式在处理复杂的对象树时可能会引入一些性能开销,因为需要在运行时遍历和操作这些对象
  • 如果应用程序对性能有非常严格的要求,那么可能需要避免使用组合模式,或者仔细评估其性能影响并采取相应的优化措施

3 ) 需要严格限制对象类型

  • 组合模式允许在对象树中组合不同类型的对象,这提供了很大的灵活性
  • 然而,在某些情况下,可能需要严格限制对象树中允许的对象类型
  • 使用组合模式可能会使这种类型限制变得更加复杂和难以维护
  • 在这种情况下,可能需要考虑使用其他设计模式或技术来实现类型限制

4 ) 不适合频繁变更的结构

  • 如果应用程序中的对象结构经常发生变化,那么使用组合模式可能会导致维护成本增加
  • 因为组合模式通常需要在多个类和方法中处理对象树的遍历和操作,当结构发生变化时,这些代码可能需要进行相应的修改和更新

5 ) 对接口有严格要求的场景

  • 在某些情况下,应用程序可能需要遵循特定的接口规范或协议,而这些规范可能不支持或不适合使用组合模式
  • 在这种情况下,可能需要考虑其他符合接口要求的设计模式或技术

6 ) 需要注意的是

  • 以上只是一些一般性的指导原则,并不适用于所有情况
  • 在实际应用中,是否使用组合模式需要根据具体的应用场景和需求进行权衡和决策

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日OJ题_BFS解决FloodFill②_力扣200. 岛屿数量

目录 力扣200. 岛屿数量 解析代码 力扣200. 岛屿数量 200. 岛屿数量 难度 中等 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方…

蓝桥杯练习题 —— A+B问题(python)

a, b map(int, input().split()) print(a b) 所用方法 a, b map(int, input().split()) 这段代码的作用是从用户输入中获取两个整数&#xff0c;并将它们分别赋值给变量 a 和 b。让我逐步解释&#xff1a; input(): 这个函数用于从用户获取输入。程序会暂停运行&#xff0…

聊聊自己12岁车龄的福克斯

1. 2005年&#xff0c;国内进入了 福克斯 ( 参数 | 询价 ) 这台车&#xff0c;中间经历了两次换代&#xff0c;而我自己的这台车则是第一批进入国内的福克斯&#xff0c;它的到来颠覆了大家当时对汽车设计的印象&#xff0c;在十年前家用车都是捷达、桑塔纳等那些古板油腻的车…

全球变暖蓝桥杯2018省赛真题

全球变暖蓝桥杯2018省赛真题 DFS大法 全球变暖 #include <bits/stdc.h> using namespace std; #define int long long bool flag; char a[1010][1010]; int cnt,n,ans0,pre_ans0,d[4][2] {1,0,-1,0,0,1,0,-1}; void dfs(int x,int y){if(x>n||x<0||y>n||y<…

德勤:《中国AI智算产业2024年四大趋势》

2023年《数字中国建设整体布局规划》的发布&#xff0c;明确了数字中国是构建数字时代竞争优势的关键支撑&#xff0c;是继移动互联网时代以来经济增长新引擎。当我们谈论数字中国的构建&#xff0c;不仅仅是在讨论一个国家级的技术升级&#xff0c;而是关乎如何利用数字技术来…

TVM Object类型系统

在TVM Object类型系统中最重要的是三个类&#xff1a;Object、ObjectPtr、ObjectRef 为什么需要这三个类&#xff1f; 设计目的&#xff1a;为了能够在不更改python前端的情况下扩展c中的语言对象&#xff0c;且能够对任何语言对象序列化。 Object&#xff1a;编译器中所有的…

GNU Autotools 套件详解

GNU Autotools 是一套用于构建和安装软件的工具,它包括了一系列的工具,如 `autoscan`, `aclocal`, `autoconf`, `autoheader`, `automake` 等。 这些工具的目的是简化软件的编译过程,使得软件能够在不同的操作系统和硬件平台上编译和运行。 历史背景 GNU Autotools 的历史…

操作系统(第四周 第一堂)

目录 回顾 进程调度&#xff08;process schedule&#xff09; 进程角度 计算机整体——调度队列 队列图 调度程序 总结 回顾 上一篇文章的重点只有一个————进程 对进程的了解包含以下几个方面&#xff1a;1、程序如何变为进程 2、进程在内存中的存储形式 3、进…

魔法工艺 Magicraft CE基址

魔法工艺 Magicraft CE基址 游戏版本&#xff1a;0.82.7 Magicraft.CT <?xml version"1.0" encoding"utf-8"?> <CheatTable CheatEngineTableVersion"45"><CheatEntries><CheatEntry><ID>19</ID><De…

socks5代理、代理IP、游戏技术与网络安全,探讨它们在跨界电商领域中的应用和重要性

首先&#xff0c;我们来理解socks5代理。socks5代理是一种网络协议&#xff0c;它通过一个中间服务器来转发客户端的网络请求&#xff0c;从而帮助用户绕过网络审查或访问地区性内容。与其前身socks4相比&#xff0c;socks5支持更多的认证方式和更复杂的网络通信&#xff0c;包…

【网站项目】校园二手交易平台小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

力扣HOT100 - 189. 轮转数组

解题思路&#xff1a; 三次反转。 先反转一次&#xff0c;再根据 k 拆分成两部分各反转一次。 class Solution {public void rotate(int[] nums, int k) {k % nums.length;reverse(nums, 0, nums.length - 1);reverse(nums, 0, k - 1);reverse(nums, k, nums.length - 1);}pu…

相机参数的意义

相机标定的意义&#xff1a; 相机标定&#xff1a;使用带有pattern的标定板来求解相机参数的过程&#xff1b;用一个简化的数学模型来代表复杂的三维到二维的成像过程&#xff1b;相机参数包括&#xff1a;相机内参&#xff08;焦距等&#xff09;&#xff0c;外参&#xff08…

node 的全局对象有哪些

node 和浏览器是两个不同的运行 js 的平台&#xff0c;对于浏览器来说&#xff0c;我们知道全局对象有window&#xff0c;对应的 node 中就是 global 常见的全局对象有 真正的全局对象 globalconsole console是宿主环境【node、浏览器】中的对象&#xff0c;所以我们在生产环…

【分布式缓存】

1. 缓存雪崩、缓存击穿与缓存穿透 1.1 缓存雪崩 缓存雪崩是指在缓存中的大量数据同时失效或过期&#xff0c;导致大量的请求直接打到数据库或后端系统&#xff0c;造成系统压力骤增&#xff0c;甚至导致系统崩溃。 原因&#xff1a; 缓存服务器宕机&#xff1a; 如果缓存服…

完全平方数(蓝桥杯,acwing,数论)

题目描述&#xff1a; 一个整数 a 是一个完全平方数&#xff0c;是指它是某一个整数的平方&#xff0c;即存在一个整数 b&#xff0c;使得 ab^2。 给定一个正整数 n&#xff0c;请找到最小的正整数 x&#xff0c;使得它们的乘积是一个完全平方数。 输入格式&#xff1a; 输…

[CUDA 学习笔记] 矩阵转置算子优化

矩阵转置算子优化 矩阵转置是一种基础的矩阵操作, 即将二维矩阵的行列进行反转. 本文主要围绕行主序的二维单精度矩阵的转置考虑相关的优化. 以下 kernel 笔者均是在 NVIDIA V100 (7.0 算力) 上进行测试的, 且选择矩阵的行列维度大小为 M2300 N1500. Version 0. 朴素实现 _…

处理慢查询时使用explain一般看哪些字段

explain之后会出现这些&#xff0c;一般就只看下面这几个字段 select_type就是查询类型&#xff0c;在我司的业务里基本上用的都是简单查询&#xff0c;在内存中处理逻辑&#xff0c;复杂查询的话排查问题比较麻烦&#xff0c;引起慢查询还会拖累数据库&#xff0c;数据库里还…

jvm运行情况预估

相关系统 jvm优化原则-CSDN博客 执行下面指令 jstat gc -pid 能计算出一些关键数据&#xff0c;有了这些数据&#xff0c;先给JVM参数一些的初始的&#xff0c;比堆内存大小、年轻代大小 、Eden和Srivivor的比例&#xff0c;老年代的大小&#xff0c;大对象的阈值&#xff0c;…

前端学习<四>JavaScript基础——05-变量的数据类型:基本数据类型和引用数据类型

数据分类 数据分为&#xff1a;静态数据、动态数据。 静态数据 静态数据是指一些永久性的数据。一般是以文件的形式存储在硬盘上&#xff0c;比如文档、照片、视频等文件。 电脑关闭后&#xff0c;静态数据仍然还在。只要不主动删掉数据或者硬盘没损坏&#xff0c;这些数据…