复合设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是复合模式 3.复合图案的例子 4.何时使用复合图案 5.下载源代码

1.简介

在本课程中,我们将讨论一个非常有趣的设计模式,即Composite Pattern。 Composite一词的英文含义是由复杂且相关的部分组成。 复合意味着“放在一起”,这就是该设计模式的全部目的。

有时您会觉得代码中需要树数据结构。 树数据结构有许多变体,但是有时需要一棵树,其中树的分支和叶子都应被统一对待。

Composite Pattern允许您将对象组合成树状结构以表示整体的层次结构,这意味着您可以创建由不同部分组成的对象树,但是可以将其视为一个整体。 Composite使客户能够统一对待单个对象和对象组成,这就是Composite Pattern的目的。

复合模式可以有很多实际的例子。 文件目录系统,java中的html表示形式,XML解析器都是良好管理的组合,并且都可以使用“组合模式”轻松表示。 但是在深入研究示例细节之前,让我们看一下有关“复合模式”的更多细节。

2.什么是复合模式

复合模式的正式定义表示,它允许您将对象组合成树形结构以表示部分整个层次结构。 复合可以使客户统一对待单个对象和对象组成。

如果您熟悉树的数据结构,您将知道树上有父母和他们的孩子。 一个父母可以有多个孩子,但每个孩子只能有一个父母。 在“复合模式”中,具有子元素的元素称为“节点”,而没有子元素的元素称为“叶子”。

复合模式使我们能够以树的形式构建对象的结构,其中既包含对象的组成又包含作为节点的单个对象。 使用复合结构,我们可以对复合物和单个对象应用相同的操作。 换句话说,在大多数情况下,我们可以忽略对象的构成与单个对象之间的差异。

复合模式有四个参与者:

  1. 零件
  2. 综合
  3. 客户

下图显示了典型的Composite对象结构。 如您所见,单亲可以有多个孩子,即“复合”,但每个孩子只有一个父母。

图1

图1

下面的类图中的Component为复合对象和叶节点中的所有对象定义了一个接口。 组件可以实现通用方法的默认行为。

复合组件的作用是定义具有子组件的组件的行为并存储子组件。 Composite还实现了与Leaf有关的操作。 这些操作可能有意义,也可能没有意义; 它取决于使用模式实现的功能。

图2

图2

叶子定义了合成中元素的行为。 它通过实现组件支持的操作来实现。 Leaf还继承了方法,这些方法对于叶子节点不一定很有意义。

客户端通过Component接口操作合成中的对象。

3.复合图案的例子

您可以在具有系统或子系统的层次结构性质且要统一对待单个对象和对象组成的任何地方实施Composite模式。 可以使用复合模式来实现文件系统,XML,HTML或办公室的层次结构(从总裁到员工)。

让我们看一个简单的示例,其中我们使用Composite Pattern在Java中实现html表示形式。 html本质上是分层的,它从<html>标记(它是父标记或根标记)开始,并且包含其他可以是父或子标记的标记。

可以使用Component类作为抽象类或接口来实现Java中的Composite Pattern。 在此示例中,我们将使用一个抽象类,其中包含复合类和叶类中使用的所有重要方法。

package com.javacodegeeks.patterns.compositepattern;import java.util.List;public abstract class HtmlTag {public abstract String getTagName();public abstract void setStartTag(String tag);public abstract void setEndTag(String tag);public void setTagBody(String tagBody){throw new UnsupportedOperationException("Current operation is not support for this object");}public void addChildTag(HtmlTag htmlTag){throw new UnsupportedOperationException("Current operation is not support for this object");}public void removeChildTag(HtmlTag htmlTag){throw new UnsupportedOperationException("Current operation is not support for this object");}public List<HtmlTag>getChildren(){throw new UnsupportedOperationException("Current operation is not support for this object");}public abstract void generateHtml();}

HtmlTag类是组件类,它定义了复合类和叶子类使用的所有方法。 这两个扩展类中应该有一些共同的方法。 因此,这些方法在上面的类中保持抽象,以强制在子类中实现它们。

getTagName()只是返回标签名称,并且两个子类(即复合类和叶类)都应使用它。

每个html元素都应该有一个开始标记和一个结束标记, setStartTagsetEndTag方法用于设置html元素的开始和结束标记,并且应该由两个子类实现,因此它们在上述类中保持抽象。

有些方法仅对复合类有用,而对叶类没有用。 只需为这些方法提供默认实现,抛出异常是这些方法的良好实现,以避免不应支持它们的对象意外调用这些方法。

generatHtml()方法是两个扩展类都应支持的操作。 为了简单起见,它仅将标签打印到控制台。

现在,让我们看一下Composite类。

package com.javacodegeeks.patterns.compositepattern;import java.util.ArrayList;
import java.util.List;public class HtmlParentElement extends HtmlTag {private String tagName;private String startTag; private String endTag;private List<HtmlTag>childrenTag;public HtmlParentElement(String tagName){this.tagName = tagName;this.startTag = "";this.endTag = "";this.childrenTag = new ArrayList<>();}@Overridepublic String getTagName() {return tagName;}@Overridepublic void setStartTag(String tag) {this.startTag = tag;}@Overridepublic void setEndTag(String tag) {this.endTag = tag;}@Overridepublic void addChildTag(HtmlTag htmlTag){childrenTag.add(htmlTag);}@Overridepublic void removeChildTag(HtmlTag htmlTag){childrenTag.remove(htmlTag);}@Overridepublic List<HtmlTag>getChildren(){return childrenTag;}@Overridepublic void generateHtml() {System.out.println(startTag);for(HtmlTag tag : childrenTag){tag.generateHtml();}System.out.println(endTag);}}

HtmlParentElement类是复合类,它实现诸如addChildTagremoveChildTaggetChildren类的方法,这些方法必须由一个类实现才能成为结构的组合。 这里的操作方法是generateHtml ,它打印当前类的标记,并遍历其子类并调用它们的generateHtml方法。

package com.javacodegeeks.patterns.compositepattern;public class HtmlElement extends HtmlTag{private String tagName;private String startTag; private String endTag;private String tagBody;public HtmlElement(String tagName){this.tagName = tagName;this.tagBody = "";this.startTag = "";this.endTag = "";}@Overridepublic String getTagName() {return tagName;}@Overridepublic void setStartTag(String tag) {this.startTag = tag;}@Overridepublic void setEndTag(String tag) {this.endTag = tag;}@Overridepublic void setTagBody(String tagBody){this.tagBody = tagBody;}@Overridepublic void generateHtml() {System.out.println(startTag+""+tagBody+""+endTag);}}

HtmlElement是叶子类,其主要工作是实现操作方法,在本示例中为generateHtml方法。 它会打印startTag ,可选的tagBody(如果有的话)以及子元素的endTag

让我们测试一下这个例子。

package com.javacodegeeks.patterns.compositepattern;public class TestCompositePattern {public static void main(String[] args) {HtmlTag parentTag = new HtmlParentElement("<html>");parentTag.setStartTag("<html>");parentTag.setEndTag("</html>");HtmlTag p1 = new HtmlParentElement("<body>");p1.setStartTag("<body>");p1.setEndTag("</body>");parentTag.addChildTag(p1);HtmlTag child1 = new HtmlElement("<p>");child1.setStartTag("<p>");child1.setEndTag("</p>");child1.setTagBody("Testing html tag library");p1.addChildTag(child1);child1 = new HtmlElement("<p>");child1.setStartTag("<p>");child1.setEndTag("</p>");child1.setTagBody("Paragraph 2");p1.addChildTag(child1);parentTag.generateHtml();}}

上面的代码将导致以下输出:

<html>
<body>
<p>Testing html tag library</p>
<p>Paragraph 2</p>
</body>
</html>

在上面的示例中,首先我们创建了一个父标记(<html>),然后向其添加一个子代,该子代是另一个复合类型(<body>),并且该对象包含两个子代(<p>)。

请注意,上述结构表示为整体层次结构,并且对父标记的generateHtml()方法的调用允许客户端统一对待对象的组成。 当它生成对象及其所有子对象的html时。

4.何时使用复合图案

  1. 当您要表示对象的整体层次结构时。
  2. 当您希望客户能够忽略对象组成和单个对象之间的差异时。 客户将统一对待复合结构中的所有对象。

5.下载源代码

这是关于“复合模式”的一课。 您可以在此处下载源代码: CompositePattern-Project

翻译自: https://www.javacodegeeks.com/2015/09/composite-design-pattern.html

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

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

相关文章

kafka 不同分区文件存储_大白话 + 13 张图解 Kafka

前言应大部分的小伙伴的要求&#xff0c;在Yarn之前先来一个kafka的小插曲&#xff0c;轻松愉快。一、Kafka基础消息系统的作用应该大部份小伙伴都清楚&#xff0c;用机油装箱举个例子所以消息系统就是如上图我们所说的仓库&#xff0c;能在中间过程作为缓存&#xff0c;并且实…

如何恢复被删短信_手机便签记事本的内容如何恢复?快试试这款好用的便签

手机便签记事本是很多人日常工作和生活中都会用到的一种辅助工具&#xff0c;它不但可以记录我们的待办事项&#xff0c;经常坚持使用的话&#xff0c;还能养成良好的生活节奏。常在河边走哪有不湿鞋&#xff0c;很多人都发生过误删的情况&#xff0c;手机便签记事本的内容如何…

分享一些在内网操作的远程办公经验

前言大家好&#xff0c;我叫孙叫兽&#xff0c;本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢&#xff0c;因为从事的开发项目比较保密&#xff0c;比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

OpenMap教程–第1部分

介绍 本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。 OpenMap的开发人员指南是非常有用的文档&#xff0c;描述了OpenMap的体系结构&#xff0c;但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用&#xff0c;但还不够。 OpenMap是用…

killall 后面信号_Linux 下使用 killall 命令终止进程的 8 大用法

Linux 的命令行提供很多命令来杀死进程。比如&#xff0c;你可以向 kill 命传递一个PID来杀死进程&#xff1b;pkill 命令使用一个正则表达式作为输入&#xff0c;所以和该模式匹配的进程都被杀死。但是还有一个命令叫 killall &#xff0c;默认情况下&#xff0c;它精确地匹配…

分享一些我的远程办公经验

前言 大家好&#xff0c;我叫孙叫兽&#xff0c;本期内容给大家分享一群在内网操作的程序员远程办公经验。为啥说是内网呢&#xff0c;因为从事的开发项目比较保密&#xff0c;比如某银行总行的新一代智能柜台项目。这些平时开发的内容不能直接和互联网进行连接。只能通过行方的…

SqlServer按中文数字排序

表数据: 按名称排序 并不能得到一二三四五六的顺序 select * from LiWei order by name 找到中文数字在一二三四五六七八九十的位置 select id,name,SUBSTRING(name,2,1) as 中文数字,charindex(SUBSTRING(name,2,1),一二三四五六七八九十) as 中文数字所在位置 from LiWei 按中…

C语言--直接插入排序【排序算法|图文详解】

一.直接插入排序介绍&#x1f357; 直接插入排序又叫简单插入排序&#xff0c;是一种简单直观的排序算法&#xff0c;它通过构建有序序列&#xff0c;对于未排序的数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 算法描述&#xff1a; 假设要排序…

python 读取sqlite存入文件_如何通过python读取sqlite数据文件

sqlite简介&#xff1a;sqlite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它的设计目标是嵌入式的&#xff0c;而且目前已经在很多嵌入式产品中使用了它(如安卓系统)&#xff0c;它占用资源非常的低&#xff0c;在嵌入式设…

分享一些前端优质的掘金小册,学完技术感觉已经超神了

大家好&#xff0c;本期内容给大家推荐一些优质的前端掘金小册&#xff0c;基本每个都是专栏小册的形式&#xff0c;比较适合初学者及工作几年的前端小伙伴&#xff0c;里面的内容讲解的比较详细&#xff0c;作者也是一线的大厂工作者。有兴趣的小伙伴快来打卡看一下吧&#xf…

sp烘焙流程_次世代86机甲战神制作全流程

1介绍Hello&#xff0c;大家好&#xff01;我叫周玉亮。首先感谢一下小左老师对我的作品的认可&#xff0c;以及给予我这次宝贵的分享机会。本次分享的是我的第一个次世代硬表面作品&#xff0c;名为《86机甲战神》&#xff0c;制作时间3周。时间还是相当紧的&#xff0c;要在3…

esper_Twitter4j和Esper:在Twitter上跟踪用户情绪

esper对于复杂事件处理和Twitter API的新手&#xff0c;我希望这是一个简短的教程&#xff0c;可以帮助他们Swift起步。 管理大数据并从中挖掘有用的信息是当前技术中最热门的讨论主题。 来自Twitter&#xff0c;Facebook和Linkedin等社交网络的半结构化数据的爆炸式增长使Hado…

前端实现流星雨特效

目录 前言 效果图&#xff1a; HTML CSS 完整代码 前言 使用htmlcss实现简单得浏览器特效&#xff0c;在编译器用导入项目&#xff0c;直接在浏览器打开即可&#xff0c;效果十分得炫酷&#xff0c;十分得哇塞&#xff0c;女朋友直呼NB! 效果图&#xff1a; HTML <!DO…

elementui中tabs切换item中的内容会变_中后台UX优化之道

前言“前台重体验&#xff0c;后台重逻辑”&#xff0c;B端谈 UX 有没有价值&#xff1f;一切电子化的今天&#xff0c;运营、审核、电销、账务……无数岗位依赖中后台系统来完成他们的日常工作&#xff0c;好的 UX 确实可以直接为这些产能提效当中后台的工程师们花费了巨大精力…

介体设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

jvm需要多长时间才能进行转义分析? 可能比您想象的要长。

这篇文章着眼于转义分析&#xff0c;特别是jvm在运行的程序中执行转义分析需要多长时间。 我做了一些观察&#xff0c;但目前还没有全部解释。 作为介绍&#xff0c;让我们绕道看看jvm -Xcomp中一个鲜为人知且使用更少的标志&#xff08;这将是一件好事&#xff09;。 该标志…

Linux常用操作指令整理,这个操作服务器实在是太方便了

目录 前言 常用指令 系统管理命令 打包压缩相关命令 关机/重启机器 Linux管道 Linux软件包管理 vim使用 用户及用户组管理 更改文件的用户及用户组 文件权限管理 更改权限 前言 由于在银行工作&#xff0c;一个项目需要在云桌面、SIT、UAT、小版本、联调环境、准生产…