设计模式—组合模式

news2024/9/23 3:26:17

定义:

组合模式(Composite Pattern)又称为合成模式、部分-整体模式(Part-Whole),主要用来描述部分与整体的关系。 定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性

本章代码:小麻雀icknn/设计模式练习 - Gitee.com 

结构:

  • 组件(Component):是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
  • 叶子节点(Leaf):在组合中表示叶子结点对象,叶子结点没有子结点。
  • 复合节点(Composite):定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

UML类图:

组合模式的分类

组合模式分为透明式的组合模式和安全式的组合模式。

透明方式

  • 透明模式的特点就是将组合对象所有的公共方法都定义在了抽象组件内,这样做的好处是客户端无需分辨当前对象是属于树枝节点还是叶子节点,因为它们具备了完全一致的接口,不过缺点就是叶子节点得到到了一些不属于它的方法,比如上面的addchild方法,这违背了接口隔离性原则。

安全方式

  • 在该方式中,将管理子构件的方法移到树枝构件中,抽象构件和树叶构件没有对子对象的管理方法,这样就避免了上一种方式的安全性问题。
  • 但由于叶子和分支有不同的接口,客户端在调用时要知道树叶对象和树枝对象的存在,所以失去了透明性。

实例:

透明模式:

组件(Component)根节点

package com.study.composite.transprant;

public abstract class GKAbstractCourse {
    public void addChild(GKAbstractCourse gkAbstractCourse){
        System.out.println("不支持添加操作");
    }
    public String getName() throws Exception{
        throw new Exception("不支持获取名称");
    }
    public void info() throws Exception{
        throw new Exception("不支持查询");
    }

}

 叶子节点(Leaf)

package com.study.composite.transprant;

import java.util.ArrayList;
import java.util.List;

public class LevelCourse extends GKAbstractCourse {
    private List<GKAbstractCourse> levelCourseList =new ArrayList<>();

    private String name;

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

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void addChild(GKAbstractCourse gkAbstractCourse) {
       levelCourseList.add(gkAbstractCourse);
    }

    @Override
    public void info() throws Exception {
        for (GKAbstractCourse gkAbstractCourse : levelCourseList) {
            gkAbstractCourse.info();
        }
    }
}

 复合节点(Composite)

package com.study.composite.transprant;

public class CommonCourse extends GKAbstractCourse {
    private String name;
    private String score;
    public CommonCourse(String name,String score){
        this.name = name;
        this.score = score;
    }

    @Override
    public String getName() {
        return name;
    }

    public String getScore() {
        return score;
    }

    @Override
    public void info() throws Exception {
        System.out.println("科目:" + this.getName());
        System.out.println("分数:" + this.getScore());
    }
}

 安全模式:

 组件(Component)根节点

package com.study.composite.safe;

public abstract class GKAbstractSafeCourse {
   String name;
   String score;

    public GKAbstractSafeCourse(String name, String score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public String getScore() {
        return score;
    }

    public abstract void info();
}

 叶子节点(Leaf)

package com.study.composite.safe;

import java.util.ArrayList;
import java.util.List;

public class LevelSafeCourse extends GKAbstractSafeCourse {
    private List<GKAbstractSafeCourse> levelCourseList =new ArrayList<>();

    public LevelSafeCourse(String name, String score) {
        super(name, score);
    }
    public void addChild(GKAbstractSafeCourse gkAbstractSafeCourse){
        this.levelCourseList.add(gkAbstractSafeCourse);
    }
    @Override
    public void info() {
         System.out.println("科目:"+ this.getName() + "总分:" + this.getScore() );
        for (GKAbstractSafeCourse item : this.levelCourseList) {
            item.info();
        }
    }
}

 复合节点(Composite)

package com.study.composite.safe;

public class CommonSafeCourse extends GKAbstractSafeCourse {
    public CommonSafeCourse(String name, String score){
        super(name,score);
    }
    @Override
    public void info() {
        System.out.println("科目:" + this.getName());
        System.out.println("分数:" + this.getScore());
    }
}

结果&&运行 

import com.study.composite.safe.CommonSafeCourse;
import com.study.composite.safe.LevelSafeCourse;
import com.study.composite.transprant.CommonCourse;
import com.study.composite.transprant.LevelCourse;

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println("Hello world!");
        CommonCourse chinese = new CommonCourse("语文", "120");
        CommonCourse English = new CommonCourse("英语", "100");
        CommonCourse Math = new CommonCourse("数学", "140");
        LevelCourse levelCourse = new LevelCourse("公共课");
        levelCourse.addChild(chinese);
        levelCourse.addChild(English);
        levelCourse.addChild(Math);
        levelCourse.info();
        System.out.println("------------安全模式---------------------");
        CommonSafeCourse history = new CommonSafeCourse("历史","120");
        CommonSafeCourse politics = new CommonSafeCourse("历史","120");
        CommonSafeCourse geography = new CommonSafeCourse("历史","120");
        LevelSafeCourse levelSafeCourse = new LevelSafeCourse("文综", "360");
        levelSafeCourse.addChild(history);
        levelSafeCourse.addChild(politics);
        levelSafeCourse.addChild(geography);
        levelSafeCourse.info();

    }
}

组合模式在源码中应用:

Map接口:HashMap putMapEntries 方法

 

场景分析:

组合模式一般的使用场景有:

  • 处理一个树形结构,比如,公司人员组织架构、订单信息等;。跨越多个层次结构聚合数据,比如,统计文件夹下文件总数;
  • 统一处理一个结构中的多个对象,比如,遍历文件夹下所有 XML类型文件内容。

为什么使用组合模式:

  • 希望一组对象按照某种层级结构进行管理,比如,管理文件夹和文件,管理订单下的商品等。树形结构天然有一种层次的划分特性,能够让我们自然地理解多个对象间的结构。
  • 需要按照统一的行为来处理复杂结构中的对象,比如,创建文件,删除文件,移动文件等。在使用文件时,我们其实并不关心文件夹和文件是如何被组织和存储的,只要我们能够正确操作文件即可,这时组合模式就能够很好地帮助我们组织复杂的结构,同时按照定义的统一行为进行操作,
  • 能够快速扩展对象组合。比如,订单下的手机商品节点可以自由挂接不同分类的手机(品牌类的,如华为、苹果),并且还可以按照商品的特性(如,价格、图片、商家、功能等)再自由地挂接新的节点组合,而查找时可以从手机开始查找,不断增加节点类型,直到找到合适的手机商品。 

组合模式优缺点 :

优点:

  • 简化客户端代码:组合模式可以让客户端代码更简单,因为客户端不需要知道处理的是单个对象还是组合对象,可以统一使用相同的方式来处理它们。
  • 增加新的构件更方便:使用组合模式可以很方便地增加新的构件,只需要实现抽象构件接口即可,不需要修改现有的代码。
  • 灵活性好:组合模式可以让你灵活地组合对象,可以随意添加、删除或替换构件,而不会影响整个系统的稳定性。
  • 易于扩展:组合模式可以很容易地扩展,可以在不修改现有代码的情况下增加新的行为。 

缺点:

  • 可能会导致设计过度复杂:如果组合模式的层次结构过于复杂,可能会导致设计过度复杂,使得代码难以理解和维护。
  • 可能会降低系统性能:由于组合模式需要递归遍历整个树形结构,可能会降低系统的性能。如果组合模式的层次结构过于复杂,可能会导致性能下降更为明显。可能会增加系统的抽象性:组合模式需要使用抽象类或接口来定义抽象构件,可能会增加系统的抽象性,降低代码的可读性和可维护性。

 

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

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

相关文章

【华为OD机试】悄悄话花费的时间【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 给定一个二叉树,每个节点上站着一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二叉树所有节点上的人都接收…

分布式事务与分布式锁

分布式事务 我要是一条狗 这块硬骨头 理都不想理&#xff0c;但是谁让我是一名程序员 本地消息表&#xff1a;说白了就是一个记录 操作信息 存到库中 成功状态改为成功&#xff0c;失败定时任务重试调用 消息队列&#xff1a;rocketMQ 半事务的典范&#xff0c;mq…

IT部门领导的角色与责任:在挑战中塑造未来

前言 在当今快节奏的商业环境中&#xff0c;IT部门领导扮演着至关重要的角色。他们需要具备技术专长&#xff0c;同时也需要展现出卓越的领导力来有效地管理团队和应对各种挑战。 一、技术创新的引领者 1. 重要角色转变 随着信息技术的迅猛发展&#xff0c;IT部门领导已逐渐…

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

目录 操作系统设计原则 操作系统的结构 简单结构 MS-DOS系统 ​编辑 UNIX系统 微内核 核心技术 缺点 操作系统设计原则 这一段希望大家自己可以好好看一下~~ 策略和机制的分离意味着操作系统可以进一步简化。在操作系统诞生之初&#xff0c;大家认为操作系统需要替用…

【有源码】buildroot根文件系统编译和常见问题

前言 编译好的含有QT5等工具包的buildroot根文件 仓库&#xff1a;https://gitee.com/wangyoujie11/atkboard_-linux_-driver 编译过程如下 1.下载源码&#xff0c;解压tar -vxjf xxx.tar.bz2 https://buildroot.org/ 这里以如下版本实验 2.在解压之后的buildroot-2019.02.…

Python学习:元组

Python 元组概念 Python 中的元组&#xff08;tuple&#xff09;是不可变的有序集合。它是一种数据类型&#xff0c;类似于列表&#xff08;list&#xff09;&#xff0c;但在创建后不能被修改。元组使用圆括号 () 来表示&#xff0c;其中的元素可以是任意类型&#xff0c;并且…

MySQl基础入门⑬

上一遍文章内容 查询结果排序 创建一个新的数据库&#xff08;假设名为xl&#xff09;&#xff1a; CREATE DATABASE xl;接下来&#xff0c;切换到新创建的数据库&#xff0c;并创建一个关于修仙者的表&#xff0c;命名为修仙者信息&#xff0c;包含至少6个中文字段&#xf…

鸿蒙一次开发,多端部署(八)典型布局场景

虽然不同应用的页面千变万化&#xff0c;但对其进行拆分和分析&#xff0c;页面中的很多布局场景是相似的。本小节将介绍如何借助自适应布局、响应式布局以及常见的容器类组件&#xff0c;实现应用中的典型布局场景。 说明&#xff1a; 在本文 媒体查询 小节中已经介绍了如何通…

一、rv1126开发之视频输入和视频编码

RV1126 H264/HEVC编码流程 一、RV1126编码的流程图&#xff1a; 二、每个代码模块详细讲解 2.1. VI模块的创建 VI模块的初始化&#xff1a;关键在于VI_CHN_ATTR_S结构体&#xff0c;这个结构体是VI设置的结构体。这个结构体的成员变量包括&#xff1a;pcVideoNode&#xff0…

【Java Web基础】一些网页设计基础(五)

文章目录 1. 图片在盒子内部垂直居中2. 底部设计&#xff0c;图片或子元素居中于父盒子&#xff08;水平、垂直&#xff09;&#xff0c;随着屏幕大小放大或缩小3. 使用thymeleaf的th:each会导致样式失效错乱问题 1. 图片在盒子内部垂直居中 用弹性盒子实现垂直居中及用css实现…

html5cssjs代码 035 课程表

html5&css&js代码 035 课程表 一、代码二、解释基本结构示例代码常用属性样式和装饰响应式表格辅助技术 一个具有亮蓝色背景的网页&#xff0c;其中包含一个样式化的表格用于展示一周课程安排。表格设计了交替行颜色、鼠标悬停效果以及亮色表头&#xff0c;并对单元格设…

使用Oxygen编辑器的项目来做团队协作

▲ 搜索“大龙谈智能内容”关注公众号▲ 扫码见我视频号上的视频 今天&#xff0c;分享一种在Oxygen中使用项目文件进行团队协作的高效方法。这种方法不仅能帮助我们轻松共享文件和文件夹&#xff0c;还能确保团队成员使用统一的项目级别选项和发布配置&#xff0c;从而提高工…

模板高级使用(非类型模板参数,特化,分离编译)

文章目录 模板没有实例化取内嵌类型报错问题非类型模板参数模板的特化函数模板的特化类模板的特化1.全特化2.偏特化 模板的分离编译 模板没有实例化取内嵌类型报错问题 首先在这里分享一个模板的常见报错问题。就是模板的在没有实例化的情况下去取模板类里面的内嵌类型这时候的…

【面试题】HashMap为什么可以插入null而Hashtable就不可以(源码分析)

首先hashmap可以插入null值&#xff0c;但是hashtable和hashcurrentHashmap是不支持的&#xff1b;这是因为在 hashmap对插入key为null进行了特殊处理&#xff0c;当插入的值为null的时候会将哈希值设置为0 但是hashtable会直接抛出异常&#xff1a; 并且hashmap是线程不…

2024全国水科技大会【发言单位】天健水务集团(杭州)有限公司

天健水务&#xff0c;始创于2003年&#xff0c;下属浙江天行健水务有限公司、杭州天勤水处理技术有限公司、杭州天行健新能源有限公司&#xff0c;是一家致力于现代化水处理设备与系统研发、生产及工程应用的国家高新技术企业。以天健智造、天健工程、天健运维的“一站式全流程…

uniapp ios证书失效

前面是按照网上查找的方法 作者大大的地址 1、一个ios账户&#xff08;688付费版&#xff09; 2、登录 Apple Developer 3、创建Identifiers ps&#xff1a;创建时需继承苹果的sdk&#xff0c;只需要一个就行 点击continue再点击Register即可 4、创建.cer证书 &…

软件测试简历,你真的会写简历吗?一周疯狂面试6家...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 简历元素 一份合格…

SqlServer数据库复习总结资料

基于课堂上学到的以及书上的看到的&#xff0c;总结出的数据库复习资料 一、数据库概述 基本概念 1.数据 数据&#xff08;Data&#xff09;是事物的符号表示&#xff0c;可以是声音、图像、文字、数字&#xff0c;也可以是计算机代码。 2.数据库 数据库&#xff08;DataBase…

WebSocket 使用示例,后台为nodejs

效果图 页面代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>WebSocket Client</title&g…

java NIO群聊系统

demo要求&#xff1a; 1&#xff09;编写一个NIO群聊系统&#xff0c;实现服务器端和客户端之间的数据简单通讯&#xff08;非阻塞&#xff09; 2&#xff09;实现多人群聊 3&#xff09;服务器端&#xff1a;可以监测用户上线&#xff0c;离线&#xff0c;并实现消息转发功…