java23种设计模式(八) -- 组合模式(结构型设计模式)

Java常见的23种设计模式是哪些? 一、什么是设计模式: 设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。 Java全套视频推荐:全新的Java300集_java零基础小白自... 阅读详情

组合模式

简介

用面向对象的方式来处理树形结构
组合多个对象形成树形结构以表示具有“整体-部分”关系的层次结构。
在组合模式中引入了抽象构件类Component,它是所有容器类和叶子类的公共父类。
角色
	Component抽象构件
		可以是接口或抽象类
		为叶子构件和容器构件对象声明接口
	Leaf叶子构件
		叶子节点没有子节点
	Composite容器构件
		容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点。

组合模式,就是在一个对象中包含其他对象,这些被包含的对象可能是终点对象(不再包含别的对象),也有可能是非终点对象(其内部还包含其他对象,或叫组对象),我们将对象称为节点,即一个根节点包含许多子节点,这些子节点有的不再包含子节点,而有的仍然包含子节点,以此类推。很明显,这是树形结构,终结点叫叶子节点,非终节点(组节点)叫树枝节点,第一个节点叫根节点。同时也类似于文件目录的结构形式:文件可称之为终节点,目录可称之为非终节点(组节点)。

角色

在组合模式结构图中包含如下几个角色

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。

  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。

  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

如果不使用组合模式,客户端代码将过多地依赖于容器对象复杂的内部实现结构,容器对象内部实现结构的变化将引起客户代码的频繁变化,带来了代码维护复杂、可扩展性差等弊端。组合模式的引入将在一定程度上解决这些问题。

下面通过简单的示例代码来分析组合模式的各个角色的用途和实现。对于组合模式中的抽象构件角色,其典型代码如下所示:

/**
*	一般将抽象构件类设计为接口或抽象类,将所有子类共有方法的声明和实现放在抽象构件类中。
*	对于客户端而言,将针对抽象构件编程,而无须关心其具体子类是容器构件还是叶子构件
**/
abstract class Component {  
    public abstract void add(Component c); //增加成员  
    public abstract void remove(Component c); //删除成员  
    public abstract Component getChild(int i); //获取成员  
    public abstract void operation();  //业务方法  
}

/**
*	作为抽象构件类的子类,在叶子构件中需要实现在抽象构件类中声明的所有方法,
*	包括业务方法以及管理和访问子构件的方法,但是叶子构件不能再包含子构件,
*	因此在叶子构件中实现子构件管理和访问方法时需要提供异常处理或错误提示。
*	当然,这无疑会给叶子构件的实现带来麻烦。
**/
class Leaf extends Component {  
    public void add(Component c) {   
        //异常处理或错误提示   
    }     
          
    public void remove(Component c) {   
        //异常处理或错误提示   
    }  
      
    public Component getChild(int i) {   
        //异常处理或错误提示  
        return null;   
    }  
      
    public void operation() {  
        //叶子构件具体业务方法的实现  
    }   
}

/**
*	在容器构件中实现了在抽象构件中声明的所有方法,既包括业务方法,
*	也包括用于访问和管理成员子构件的方法,如add()、remove()和getChild()等方法。
*	需要注意的是在实现具体业务方法时,由于容器构件充当的是容器角色,包含成员构件,
*	因此它将调用其成员构件的业务方法。在组合模式结构中,由于容器构件中仍然可以包含容器构件,
*	因此在对容器构件进行处理时需要使用递归算法,
*	即在容器构件的operation()方法中递归调用其成员构件的operation()方法。
**/
class Composite extends Component {  
    private ArrayList<Component> list = new ArrayList<Component>();  
      
    public void add(Component c) {  
        list.add(c);  
    }  
      
    public void remove(Component c) {  
        list.remove(c);  
    }  
      
    public Component getChild(int i) {  
        return (Component)list.get(i);  
    }  
      
    public void operation() {  
        //容器构件具体业务方法的实现  
        //递归调用成员构件的业务方法  
        for(Object obj:list) {  
            ((Component)obj).operation();  
        }  
    }     
}

具体代码实例

/**
 * 抽象文件类
 */
public abstract class AbstractFile {

    public abstract void add(AbstractFile file);

    public abstract void remove(AbstractFile file);

    public abstract AbstractFile getChild(int i);

    public abstract void killVirus();

}

/**
 * Image文件类
 */
public class ImageFile extends AbstractFile{

    private String name;

    public ImageFile (String name) {
        this.name = name;
    }

    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public AbstractFile getChild(int i) {
        System.out.println("对不起,不支持该方法!");
        return null;
    }

    public void killVirus() {
        // 模拟杀毒
        System.out.println("----对图像文件'" + name + "'进行杀毒----");

    }

}

/**
 * 文本文件类
 */
public class TextFile extends AbstractFile{

    private String name;

    public TextFile (String name) {
        this.name = name;
    }

    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public AbstractFile getChild(int i) {
        System.out.println("对不起,不支持该方法!");
        return null;
    }

    public void killVirus() {
        // 模拟杀毒
        System.out.println("----对文本文件'" + name + "'进行杀毒----");

    }

}

/**
 * 视频文件类
 */
public class VideoFile extends AbstractFile{
    private String name;
    public VideoFile (String name) {
        this.name = name;
    }

    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    public AbstractFile getChild(int i) {
        System.out.println("对不起,不支持该方法!");
        return null;
    }

    public void killVirus() {
        // 模拟杀毒
        System.out.println("----对视频文件'" + name + "'进行杀毒----");

    }

}


/**
 * 文件夹类
 */
public class Folder extends AbstractFile{
    private ArrayList<AbstractFile> fileList = new ArrayList<AbstractFile>(); // 规定集合中成员类型
    private String name;
    public Folder(String name) {
        this.name = name;
    }

    public void add(AbstractFile file) {
        fileList.add(file);
    }

    public void remove(AbstractFile file) {
        fileList.remove(file);
    }

    public AbstractFile getChild(int i) {
        return (AbstractFile)fileList.get(i); // 强制转换为类型
    }

    public void killVirus() {
        System.out.println("****对文件夹'" + name + "'进行杀毒****"); // 模拟杀毒
        // 递归调用成员构件的杀毒方法
        for (Object obj :fileList) {
            ((AbstractFile)obj).killVirus();
        }
    }
}

测试类

public class ApiTest {

    @Test
    public void testCommodity() throws Exception {
        AbstractFile file1, file2, file3, file4, file5, folder1, folder2, folder3, folder4;
        folder1 = new Folder("Jim的资料");
        folder2 = new Folder("图像文件");
        folder3 = new Folder("文本文件");
        folder4 = new Folder("视频文件");

        file1 = new ImageFile("小龙女.jpg");
        file2 = new ImageFile("张无忌.gif");
        file3 = new TextFile("九阴真经.txt");
        file4 = new TextFile("葵花宝典.doc");
        file5 = new VideoFile("笑傲江湖.rmvb");

        folder2.add(file1);
        folder2.add(file2);
        folder3.add(file3);
        folder3.add(file4);
        folder4.add(file5);
        folder1.add(folder2);
        folder1.add(folder3);
        folder1.add(folder4);

        folder1.killVirus();
    }
}

在这里插入图片描述

由于在本实例中使用了组合模式,在抽象构件类中声明了所有方法,包括用于管理和访问子构件的方法,如add()方法和remove()方法等,因此在ImageFile等叶子构件类中实现这些方法时必须进行相应的异常处理或错误提示。在容器构件类Folder的killVirus()方法中将递归调用其成员对象的killVirus()方法,从而实现对整个树形结构的遍历。

优缺点

  1. 主要优点

    组合模式的主要优点如下:

    • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。

    • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。

    • 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。

    • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

  2. 主要缺点

    组合模式的主要缺点如下:

    • 在增加新构件时很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件,使用组合模式时,不能依赖类型系统来施加这些约束,因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。
JAVA设计模式总结之23种设计模式 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。 阅读详情

相关推荐

GAN网络详解析

介绍目前常见的GAN网络,以及GAN网络的基本组成

wm199的博客 6504

设计模式之结构型模式

设计模式复习 结构型模式

weixin_44422636的博客 1271

SAP生产订单(创建-下达-发料-报工-入库)全流程及反向流程

SAP创建下达报工入库发料以及取消发料取消入库,批量下达删除关闭,生产订单出入库查询和状态更改查询记录

weixin_38974136的博客 2万+

【设计模式】——结构型设计模式

结构型设计模式涉及如何组合类和对象以获得更大得结构。结构类模式采用继承机制来组合接口或实现。 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能得一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大得灵活性,而这种机制用静态组合是不可能实现的。 适配器(Adapter) 意图:将一个类得接口转换成客户希望得另外一个接口,Adapter模式使得...

一只蓝精灵 552

Cibersort免疫浸润 --- 详细教程

免疫浸润是指免疫细胞如淋巴细胞、浆细胞、巨噬细胞等进入到组织或器官中,并在这些组织或器官中发挥免疫功能的过程。免疫细胞的浸润可以是炎症反应的一部分,也可以是针对感染、肿瘤或其他疾病的免疫应答的一部分。免疫浸润通过调节免疫反应和炎症反应的程度和类型,起到维护机体免疫平衡和清除异常细胞或病原体的作用。在某些情况下,免疫浸润可能导致炎症反应过度,引起组织损伤,例如自身免疫性疾病。因此,免疫浸润在许多疾病的诊断和治疗中都具有重要的意义。免疫浸润可以通过组织切片染色和免疫组织化学等方法观察和分析。

ZxVSaccount的博客 9105

华为Atlas 300I推理卡驱动安装避坑指南:不同安装方式的选择与优化

本文详细解析华为Atlas 300I推理卡驱动安装的三种主流方式(.run、.rpm和源码编译),提供关键环境检查步骤、安装流程优化建议及常见问题解决方案,帮助开发者高效完成芯片推理卡部署并规避典型安装陷阱。

q9w8e7r6t5的博客 431

23种设计模式-4结构型设计模式

依赖: 是一个类方法内部出现一个新类型,关联组合聚合是语义上的划分。比如接口实现‘继承、实现父类 子类和父类之间的关系。1:纵向关系 继承/实现父类 关系密切。2:横向关系 依赖、关联、组合、聚合。结构型设计模式 关注类和类的之间关系。面向对象-类之间的功能关系分2类。...

170

Unity UGUI深度优化

Unity UGUI优化相关

不定时分享所学所得,包括游戏开发和其他收获! 2717

设计模式05——结构型模式

一、概述  结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。  结构型模式分为以下 7 种:   1、代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性   2、适配器(Adapter)模式:将一个类的接口转

如不來的博客 1318

【库卡机器人】接线步骤

准备X11插头接线,X11插头可以接入机器人外部安全回路接线,其中外部使能信号线也接在此接口上,如果机器人系统没有配置外部使能装置,那个此接口上的外部使能信号端须短接,短接规则为:20-21、23-22、31-30、33-32。持续按住使能键,保持使能上电状态,分别按住示教器右侧每个轴对应的+或-按键,测试机器人每一个轴是否能正常运行,如果一切正常,说明机器人控制正常,机器人可以正常使用。将一根黄绿色等电位线接入其中的一个接地端,并与机器人的接地端相连,使得控制柜与机器人等电位。

qq_45161762的博客 9439

Unity 面试篇|(六)数据结构和算法篇 【全面总结 | 持续更新】

先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的),将这个数替换堆顶,并调整结构使之仍然是一个最小堆,这样遍历完后,堆中的10000个数就是所需的最大的10000个。桶排序是计数排序的升级版。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。这样处理就可以分别在每个文件的10^6个数据中找出最大的10000个数,合并到一起在再找出1000*10000中的最终的结果。

游戏开发小Y的博客 12万+

Java中23种设计模式的详细介绍

Java开发中23种设计模式详细介绍设计模式介绍设计模式分类设计模式六大原则开闭原则(Open Close Principle)里氏代换原则 设计模式介绍 设计模式(Design Patterns): 一套被反复使用,多数人知晓,经过分类编目,代码设计的总结 使用设计模式是为了可重用代码,让代码更容易理解,保证代码可靠性 项目中合理运用设计模式可以完美的解决很多问题,每种模式都有相应的原理...

攻城狮Chova的博客 1万+

YOLOv8魔改系列:将CIoU替换成Wise-IoU,飞速涨点

将YOLOv8中CIoU替换成Wise-IoU,实现飞速涨点

qq_66386046的博客 2678

瑞_23种设计模式_组合模式

本文章为瑞_系列专栏之《23种设计模式》的组合模式篇。组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

阿瑞——从事Java后端,喜欢研读源码、自研框架、分享经验 1900

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

23种设计模式学习导航(Java完整版)

本篇文章是作者对23种设计模式学习的一个总结,包含设计模式的三大分类(创建型5种,结构型7种,行为型11种)和七个面向对象设计原则,为了方便大家学习,现将23种设计模式的连接进行了整理,希望对大家有所帮助。ps:后续会带来设计模式的组合使用,敬请期待。

让~学习~成为一种习惯(橡 皮 人の技术博客) 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【玩转23种Java设计模式】结构型模式篇:组合模式

组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示"部分-整体"的层次关系。其核心思想是通过统一接口处理叶子对象(单个元素)和组合对象(容器元素),使客户端无需区分操作的是单个对象还是整个组合结构。

程序员云帆哥的博客 2012

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

23种设计模式【结构型模式】详细介绍之【组合模式】

设计模式组合模式允许将对象组合成树状结构,从而能够统一处理个体对象和组合对象。适用于表示层次结构的数据,如文件系统、图形界面组件、组织结构等。组合模式通过将对象组合成树形结构,使客户端可以统一地处理单个对象和组合对象,增强了系统的灵活性和可扩展性。它是一种非常有效的方式来管理和操作层次结构数据,简化了复杂结构的管理。版权声明:原创博主:牛哄哄的柯南[哈哈][抱拳]加油!共同努力!Keafmd牛哄哄的柯南,期待你的三连+关注~~

『愚』的博客 1364

Java23种设计模式详解

提供了一种方式来封装一组具有相关联的或相互依赖的对象的创建。一个抽象工厂定义了一个接口,用于创建相关或依赖对象的家族,而实际的具体工厂则负责生成具体的对象。下面是一个使用Java实现的抽象工厂模式的简单示例:假设我们有一个图形应用程序,需要绘制不同类型的形状(如圆形、矩形等)和颜色填充策略(如红色、蓝色等)。每种形状都可以有不同的颜色填充,这就构成了两个相关的对象家族。// 抽象产品接口:形状// 具体产品:圆形@Override// 具体产品:矩形@Override。

2301_76508397的博客 3791

Java二十三种设计模式-组合模式(11/23)

组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构(树形结构)来表示“部分-整体”的层次关系。组合模式使得用户可以一致地对待单个对象和组合对象。组合模式提供了一种有效的方法来构建和表示层次化结构,使得客户端可以一致地处理单个对象和组合对象。通过本文的深入分析,希望读者能够对组合模式有更全面的理解,并在实际开发中做出合理的设计选择。Java二十三种设计模式-单例模式(1/23)Java二十三种设计模式-工厂方法模式(2/23)

小相探索IT世界 1636

设计模式--组合模式【结构型模式】

组合模式又叫作整体-部分模式,它将对象组合成树状的层次结构,用来表示整体-部分的关系,使用户对单个对象和组合对象具有一致的访问性,是一种结构型模式。

weixin_42118323的博客 1455

【23种设计模式】结构型模式详细介绍

本文为 【23种设计模式】结构型模式 相关内容介绍,下边将对适配器模式,桥接模式,组合模式,装饰模式,外观模式,亨元模式,代理模式,具体包括它们的特点与实现等进行详尽介绍~

小新要变强的博客 1417

设计模式(九)结构型:组合模式详解

组合模式(Composite Pattern)是 GoF 23 种设计模式中的结构型模式之一,其核心价值在于将对象组织成树形结构以表示“部分-整体”的层次关系,并使得客户端可以统一地处理单个对象和组合对象。

谦与谦寻的神隐 1166

23种设计模式介绍以及在Java中的实现

文本详细总结了23种设计模式以及他们如何应用到java中,并提供了大量的示例代码。 文章中的示例源码在github上:https://github.com/anxpp/JavaDesignPattern。 如果本文对您有所帮助,请帮忙点个赞扩散一下,谢谢!

anxpp的博客 4万+

Java设计模式-结构型模式设计模式-组合模式

Java设计模式-结构型模式设计模式-组合模式

Fatter$hday的博客 948

Java23种设计模式——12.结构型模式之组合模式

Java中除去有设计原则之外,还有23中设计模式。 这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,而这些设计模式可以解决一些特定的问题。 并且在这些模式中,可以说是将语言的使用体现的淋漓尽致。 那我们今天要学习结构型模式中的组合模式! 组合模式 首先我们先看一下什么叫组合模式,直接百度百科 额、可能不是很明白,但是我们说一个东西大家就知道了,比如说菜单 菜单就是将一个一个的部分构成一个整体的菜单。 组合模式的定义与特点 组合(Composite)模式的定义...

胖子胖子大胖子的博客 1177

全面解读Java的23种设计模式

需要注意的是,混合使用设计模式要谨慎,不要过度使用设计模式,以免代码过于复杂和难以维护。选择合适的设计模式和合适的组合方式,可以使代码更加简洁、高效和易于维护。

weixin_39158966的博客 3265
上一篇: java23种设计模式(七) -- 桥接模式(结构型设计模式)
下一篇: java23种设计模式(九) -- 装饰器模式(结构型设计模式)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值