【设计模式深度剖析】【4】【结构型】【组合模式】| 以文件系统为例加深理解

本文主要是介绍【设计模式深度剖析】【4】【结构型】【组合模式】| 以文件系统为例加深理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

👈️上一篇:适配器模式

设计模式深度剖析-专栏👈️

目 录

  • 组合模式
  • 定义
    • 英文原话
    • 直译
    • 如何理解?
  • 3个角色
    • UML类图
    • 代码示例
  • 组合模式的优点
  • 组合模式的使用场景
  • 示例解析:文件系统

组合模式

组合模式(Composite Pattern)也叫合成模式,用来描述部分与整体的关系。

  • 高层模块调用简单。一棵树形结构中的所有节点都是 Component,局部和整体对调用者来说没有任何区别,即高层模块不必关心自己处理的是单个对象还是整个组合结构**,**简化了高层模块的代码。
  • 节点自由增加。使用组合模式后,如果想增加一个树枝节点、树叶节点只需要找到其父节点即可。

当我们发现需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

定义

英文原话

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

直译

将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端能够统一地处理单个对象和对象的组合。

如何理解?

叶子构件和容器构件实现了抽象构件,即实现了相同的接口,用户对单个对象和组合对象的使用具有一致性。

3个角色

UML类图

CompositePattern.png

组合模式(Composite Pattern)允许我们将对象组合成树形结构以表示“部分整体”的层次结构,使得客户端以统一的方式处理单个对象和对象的组合。以下是组合模式中的主要角色:

  1. 抽象构件(Component):它可以是接口或抽象类,为叶子和容器对象声明接口,在该接口中包含用于管理子对象的方法以及用于自身操作的方法。在组合模式中,抽象构件定义了叶子和容器构件的共同行为。
  2. 叶子构件(Leaf):叶子对象继承自抽象构件,它没有子节点,通常用于实现抽象构件中的业务方法。在组合结构中,叶子节点没有子节点,其实现了在抽象构件中定义的行为。
  3. 容器构件(Composite):容器对象也继承自抽象构件,并包含一组子构件。它实现了在抽象构件中定义的行为,并提供了添加、删除和访问其子对象的方法。容器构件可以包含其他容器或叶子,从而实现复杂的树形结构。
  4. 客户端(Client):通过抽象构件接口与组合结构进行交互。对于客户端而言,叶子对象和容器对象是一致的,客户端不需要区分它们。

代码示例

以下是一个简单的Java示例来说明组合模式:

// 抽象构件  
public interface Component {void operation();
}
// 叶子构件  
public class Leaf implements Component{@Overridepublic void operation() {// 业务处理逻辑System.out.println("leaf...");}
}
// 容器构件  
public class Composite implements Component {// 构件容器private ArrayList<Component> componentList = new ArrayList<>();// 添加构件public void add(Component component) {this.componentList.add(component);}// 删除构件public void remove(Component component) {this.componentList.remove(component);}// 获取子构件public ArrayList<Component> getChild() {return this.componentList;}@Overridepublic void operation() {// 业务逻辑System.out.println("branch...");}
}
// 客户端代码  
public class DemoTest {public static void main(String[] args) {// 创建一个根节点Composite root = new Composite();root.operation();// 创建树枝节点Composite branch = new Composite();// 创建叶子节点Leaf leaf = new Leaf();// 构建树形结构root.add(branch);branch.add(leaf);display(root);}// 遍历树(递归)public static void display(Composite root) {for (Component c : root.getChild()) {if(c instanceof Leaf){// 如果节点类型是叶子节点c.operation();}else{// 树枝节点c.operation();display((Composite) c);}}}
}
/* Output:
branch...
branch...
leaf...
*///~

在这个例子中,我们有一个Component接口,它定义了一个名为operation的方法。Leaf类实现了这个接口,并提供了具体的实现。Composite类同样实现了Component接口,并维护了一个子组件的列表。

组合模式的优点

  1. 高层模块调用简单。一棵树形机构中的所有节点都是 Component,局部和整体对调用者来说没有任何区别即高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
  2. 节点自由增加。使用组合模式后,如果想增加一个树枝节点、树叶节点只需要找到其父节点即可。

组合模式的使用场景

使用组合模式的典型场景如下。

  1. 需要描述对象的部分和整体的等级结构,如树形菜单、文件和文件夹管理
  2. 需要客户端忽略个体构件和组合构件的区别,平等对待所有的构件

示例解析:文件系统

FileSystemDemo.png

在生活中,一个常见的组合模式的例子是文件系统。文件系统中的文件和文件夹可以看作是组合模式的实现,其中文件夹可以包含文件和其他文件夹(子文件夹),而文件则不包含任何子项。

以下是使用Java实现的示例,模拟了一个简单的文件系统:

// 抽象构件:文件或文件夹  
public interface FileSystemElement {  void display();  
}  
// 叶子构件:文件  
public class File implements FileSystemElement {  private String name;  public File(String name) {  this.name = name;  }  @Override  public void display() {  System.out.println("File: " + name);  }  
}  
// 容器构件:文件夹  
public class Folder implements FileSystemElement {  private String name;  private List<FileSystemElement> children = new ArrayList<>();  public Folder(String name) {  this.name = name;  }  public void add(FileSystemElement element) {  children.add(element);  }  public void remove(FileSystemElement element) {  children.remove(element);  }  @Override  public void display() {  System.out.println("Folder: " + name);  for (FileSystemElement child : children) {  child.display();  }  }  
}  
// 客户端代码
public class DemoTest {public static void main(String[] args) {// 创建文件夹和文件  Folder rootFolder = new Folder("root");Folder documentsFolder = new Folder("Documents");Folder picturesFolder = new Folder("Pictures");File file1 = new File("example.txt");File file2 = new File("image.jpg");// 将文件和文件夹添加到对应的父文件夹中  rootFolder.add(documentsFolder);rootFolder.add(picturesFolder);documentsFolder.add(file1);picturesFolder.add(file2);// 显示整个文件系统的结构  rootFolder.display();}
}/* Output:
Folder: root
Folder: Documents
File: example.txt
Folder: Pictures
File: image.jpg
*///~

在这个示例中,FileSystemElement是抽象构件接口,它声明了一个display方法用于显示文件或文件夹的信息。File类实现了这个接口,表示一个具体的文件。Folder类也实现了这个接口,表示一个文件夹,并且它有一个children列表来存储其子元素(文件和文件夹)。Folder类还提供了添加和删除子元素的方法。

DemoTest类的main方法中,我们创建了一个根文件夹rootFolder,并添加了documentsFolderpicturesFolder两个子文件夹。接着,我们向这两个文件夹中分别添加了一个文件和图片。最后,我们调用rootFolderdisplay方法来显示整个文件系统的结构。

这个输出展示了组合模式中的层次结构,其中文件夹可以包含文件和子文件夹,而文件则不包含任何子项。

👈️上一篇:适配器模式

设计模式深度剖析-专栏👈️

这篇关于【设计模式深度剖析】【4】【结构型】【组合模式】| 以文件系统为例加深理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006997

相关文章

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加