当前位置: 首页 > news >正文

设计模式14——组合模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

组合模式(Composite)

是一种行为型模式。

目录

一、概述

1.1、主要的角色有三种:

1.2、直观的理解组合模式:

1.3、技术角度,描述对象之间关系的UML图:

二、举例

2.1、分析如下:

2.2、对象之间的关系用UML图表示如下:

2.3、Java实现代码如下:


一、概述

1、将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性;
2、基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。

1.1、主要的角色有三种:

  1. 组合(或组件)的抽象类或接口
  2. 分支类
  3. 叶子类

1.2、直观的理解组合模式:

其实可以把组合模式当做建立一个树形结构,然后可以对这个树的所有节点进行统一操作,同样这个树还可以根据需要添加删除其它节点或树,从而组成更大的树或更小的树。

1.3、技术角度,描述对象之间关系的UML图:

二、举例

简单举例,如下图所示,我们要实现这个结构,并且打印每个节点的名字。

2.1、分析如下:

1、分析上述问题:

  • 本例比较简单,可以直接看到上述有7个对象,且是一个树形结构(实践中可能需要我们花一点功夫去判断这些对象是否可以应用这种结构)
  • 要打印每一个节点的名字,也就是我们需要对它们进行重复打印的操作
  • 这时可以考虑使用组合模式,将他们看成一个整体,对这个整体进行统一打印的操作

2、针对角色和方法设计上:

组合(或组件)的抽象类或接口

  • 创建一个抽象节点

分支类

  • 本例有三个分支,名字需要分别设置

叶子类

  • 本例有四个叶子,名字需要分别设置

自定义方法:

  • 输出本节点名字

2.2、对象之间的关系用UML图表示如下:

2.3、Java实现代码如下:

组合(组件)的抽象类:

abstract class Component {protected String name;public Component(String name) {this.name = name;}public abstract void add(Component component);public abstract void remove(Component component);public abstract void display(int depth);
}

分支类:

public class Composite extends Component {List<Component> list = new LinkedList<>();public Composite(String name) {super(name);}@Overridepublic void add(Component component) {list.add(component);}@Overridepublic void remove(Component component) {list.remove(component);}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) { //每个分支节点自己要干的事情,根据实际需要编写System.out.print("-");}System.out.println(this.name);for (Component component : list) { //遍历此分支节点的子节点,必须要有component.display(depth + 2);}//...}
}

叶子类:

public class Leaf extends Component {public Leaf(String name) {super(name);}@Overridepublic void add(Component component) {System.out.println("叶子节点没有添加子节点功能!");//...}@Overridepublic void remove(Component component) {System.out.println("叶子节点没有删除子节点功能!");//...}@Overridepublic void display(int depth) {for (int i = 0; i < depth; i++) { //每个叶子节点自己要干的事情,根据实际需要编写System.out.print("-");}System.out.println(this.name);//...}
}

 主程序(发起请求的类):

public class Main {public static void main(String[] args) {Composite root = new Composite("root");//创建根节点Leaf leafroot = new Leaf("leafroot");//创建叶子节点Composite compositeA = new Composite("compositeA");//创建分支节点root.add(leafroot);root.add(compositeA);Leaf leafA = new Leaf("leafA");//创建叶子节点Composite compositeAA = new Composite("compositeAA");//创建分支节点compositeA.add(leafA);compositeA.add(compositeAA);Leaf leafAAA = new Leaf("leafAAA");//创建叶子节点Leaf leafAAB = new Leaf("leafAAB");//创建叶子节点compositeAA.add(leafAAA);compositeAA.add(leafAAB);root.display(1);}
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞吧!如果有建议,也请评论指教和讨论!

http://www.lryc.cn/news/351765.html

相关文章:

  • MyBatis面试题(Mybaits的优点、缺点、适用场合、与Hibernate有哪些不同)
  • python写接口性能测试
  • 《暮色将尽》跨越世纪的历程,慢慢走向并完善自我
  • python-鸡兔同笼问题:已知鸡和兔的总头数与总脚数。求笼中鸡和兔各几只?
  • 【NumPy】关于numpy.transpose()函数,看这一篇文章就够了
  • 什么是住宅IP代理?为什么需要家庭 IP 代理
  • Java方法的重载
  • RabbitMQ 消息队列安装及入门
  • K8S认证|CKA题库+答案| 14. 排查故障节点
  • Linux:网络管理命令之ss
  • 数据结构-队列(带图详解)
  • python文件名通常以什么结尾
  • 前端javascript 中 JSON.parse() 的作用
  • 【Linux学习】进程基础API
  • 音视频及H264/H256编码相关原理
  • 查看cpu进程数
  • MySQL优化篇
  • Python3 笔记:部分专有名词解释
  • javaAPI文档中文版(JDK11在线版)java帮助文档,掌握文档java学习事半功倍。
  • 移动端适配:vw适配方案
  • 实战Java虚拟机-实战篇
  • 力扣:349. 两个数组的交集
  • 深度学习之基于Matlab的BP神经网络交通标志识别
  • Linux备份服务及rsync企业备份架构(应用场景)
  • 用手机打印需要下载什么软件
  • Storm在Java中的应用
  • Java 面试题日常练习
  • 卷爆短剧出海:五大关键,由AIGC重构
  • LLM实战:当网页爬虫集成gpt3.5
  • Flutter底部导航栏和顶部Tab切换完整代码