Java设计模式之结构型-组合模式(UML类图+案例分析)

news2025/4/22 8:25:56

目录

一、基础概念

二、UML类图

三、角色分析

四、案例分析

1、基本实现

2、菜单遍历 

五、总结 


一、基础概念

组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。

二、UML类图

三、角色分析

角色描述
抽象构件(Component)角色定义参与组合对象的共有方法和属性,可以是接口或抽象类
叶构件(Leaf)角色基本构件类,无子构件,实现抽象构件角色所定义的接口
容器构件(Composite)角色存储子构件,实现子构件的相关操作,定义子构件的添加、删除等方法

四、案例分析

1、基本实现

抽象构件:

public abstract class Component {

  public void addComponent(Component component){

  }

  public void remove(Component component){

  }

  public Component getComponent(int i){
    return null;
  }

  public abstract void operation();

}

叶子构件:

public class Leaf extends Component{

    @Override
    public void operation() {

    }

}

容器构件:

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

public class Composite extends Component{

    private List<Component> componentList = new ArrayList<>();

    @Override
    public void addComponent(Component component) {
        componentList.add(component);
    }

    @Override
    public void remove(Component component) {
        componentList.remove(component);
    }

    @Override
    public Component getComponent(int i) {
        return componentList.get(i);
    }

    @Override
    public void operation() {
        for(Component component : componentList){
            component.operation();
        }
    }

}

主方法测试:

public class Client {

    public static void main(String[] args) {

        Component leaf1 = new Leaf();
        Component leaf2 = new Leaf();

        Composite composite1 = new Composite();
        composite1.addComponent(leaf1);
        composite1.addComponent(leaf2);

        Component leaf3 = new Leaf();
        Component leaf4 = new Leaf();

        Composite composite2 = new Composite();
        composite2.addComponent(leaf3);
        composite2.addComponent(leaf4);
        composite2.addComponent(composite1);

        composite2.operation();
    }
}

创建了两个叶节点leaf1和leaf2,一个复合组件composite1,组合包含leaf1和leaf2。

创建了两个叶节点leaf3和leaf4,一个复合组件composite2,组合包含leaf3、leaf4以及复合组件composite1。

调用composite2的operation方法,会遍历其下的所有子组件并调用其operation方法。

综上,这段基础代码演示了通过组合模式将对象组合成树状层次结构,通过调用根节点操作使得递归调用所有子节点的操作,实现统一处理个别对象和组合对象的情形,以达到“合成复用原则”。

2、菜单遍历 

我们平时用到的管理系统肯定会有1级菜单,2级菜单,3级菜单甚至4级菜单等等,下面就举一个更形象的例子来实现遍历菜单的功能。

菜单组件:

public abstract class MenuComponent {
  //菜单名
  protected String menuName;

  //菜单层级
  protected int level;

  //添加子菜单
  public void addMenu(MenuComponent menuComponent){}

  //移除子菜单
  public void removeMenu(MenuComponent menuComponent){}

  //获取指定的子菜单
  public MenuComponent getChildMenu(int index){
    return null;
  }

  //获取菜单名称
  public String getMenuName(){
    return menuName;
  }

  //打印菜单名称(子菜单或菜单项)
  public abstract void printMenu();
}

菜单:

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

public class Menu extends MenuComponent{

    //存储菜单或者菜单项
    private List<MenuComponent> menuComponentList = new ArrayList<>();

    public Menu(String menuName,int level){
        this.menuName = menuName;
        this.level = level;
    }

    @Override
    public void addMenu(MenuComponent menuComponent) {
        menuComponentList.add(menuComponent);
    }

    @Override
    public void removeMenu(MenuComponent menuComponent) {
        menuComponentList.remove(menuComponent);
    }

    @Override
    public MenuComponent getChildMenu(int index) {
        return menuComponentList.get(index);
    }

    @Override
    public void printMenu() {
        //打印菜单名称
        for (int i=0;i<level;i++){
            System.out.print("-");
        }
        System.out.println(menuName);
        for (MenuComponent component:menuComponentList){
            component.printMenu();
        }
    }

}

菜单项:

public class MenuItem extends MenuComponent{

    public MenuItem(String menuName,int level){
        this.menuName = menuName;
        this.level = level;
    }

    @Override
    public void printMenu() {
        for (int i=0;i<level;i++){
            System.out.print("-");
        }
        System.out.println(menuName);
    }
}

主方法测试:

public class ManageSystem {
    public static void main(String[] args) {
        //创建根目录
        MenuComponent menuComponent = new Menu("系统管理",1);
        //添加2个子菜单项
        menuComponent.addMenu(new MenuItem("老师管理",2));
        MenuComponent menu2 = new Menu("学生管理",2);
        //创建2级目录
        menu2.addMenu(new MenuItem("新增学生",3));
        menu2.addMenu(new Menu("修改学生",3));
        menu2.addMenu(new MenuItem("修改学生",3));
        menu2.addMenu(new Menu("删除学生",3));
        menuComponent.addMenu(menu2);
        menuComponent.printMenu();
    }
}

运行结果:

五、总结 

优点:

定义类层次结构更清晰,提高复用性。

简化客户端代码,统一对待单个对象和组合对象。

更容易在组合对象上新增功能。

缺点:

设计较复杂,增加系统实现难度。

不容易限制容器构件中的构件。

应用场景:

操作的对象具有递归树形结构时。

需要统一对待单个对象和组合对象时。

符合的原则:

1、组合复用原则(Composite Reuse Principle)

组合模式是组合复用原则最典型的体现,它通过组合方式实现对对象的复用。

2、整体-部分关系原则

组合模式中容器和叶节点是整体与部分的关系,形成一个递归的树形结构。

3、开闭原则(Open Close Principle)

组合模式对扩展开放,可以通过添加新的叶节点或容器实现扩展,而无需修改原有代码。

4、单一职责原则(Single Responsibility Principle)

组合模式中各部分职责明确,容器构件用于存储组件,叶构件用于基本行为。

5、里氏替换原则(Liskov Substitution Principle)

组合模式确保所有构件遵循统一接口约定,父对象能被子对象替换。

组合模式通过将对象组织成树形结构,模拟出复杂对象的结构关系,然后统一处理个别对象和组合对象,它充分利用了递归和层次性的对象模型来模拟复杂对象,但增加了系统的复杂性。应根据需要权衡使用,不能滥用。

综上,组合模式通过递归组合实现统一管理复杂对象,但会增加系统复杂度,需要谨慎使用。

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

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

相关文章

《网络安全标准实践指南》(72页)

导读 摘要&#xff1a;为指导网络数据安全风险评估工作&#xff0c;发现数据安全隐患&#xff0c;防范数据安全风险&#xff0c;依据《中华人民共和国网络安全法》《中华人民共和国数据安全法》《中华人民共和国个人信息保护法》等法律法规&#xff0c;参照数据安全相关国家标…

[MySQL]MySQL表的操作

[MySQL]表的操作 文章目录 [MySQL]表的操作1. 创建表2. 创建表的示例3. 查看表4. 修改表5. 删除表6. 关于表操作 1. 创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释信息],field3 dat…

使用VSC从零开始写一个Vue前端

使用Visual Studio Code&#xff08;VSC&#xff09;进行Vue开发非常方便&#xff0c;下面是一些基本步骤&#xff1a; 安装Node.js&#xff1a;Vue.js是基于Node.js的&#xff0c;所以首先需要安装Node.js。你可以从Node.js官方网站&#xff08;https://nodejs.org&#xff09…

Acwing.859 Kruskal算法求最小生成树(Kruskal算法)

题目 给定一个n个点m条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。 求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出impossible。 给定一张边带权的无向图G(V,E)&#xff0c;其中V表示图中点的集合&#xff0c;E表示图中边…

Linux - CentOS 二进制安装 MySQL 8.0.31(非常实用)

一、下载 mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz 下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions) 具体如下图所示&#xff1a; 二、将 mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz 放入到服务器的 /usr/local &#xff08;路径可…

书法vr实景授课极大丰富了艺术家的表现语言

为了加强新形势下中华优秀传统文化教育&#xff0c;探索现代科学技术与传统文化的结合。VR公司深圳华锐视点不断创新VR虚拟现实技术在传统文化方面的体验活动&#xff0c;激发学生对传统文化的学习兴趣&#xff0c;树立民族文化自信!搭建书法授课VR虚拟场景&#xff0c;为学生创…

vue2基础用法原理

本篇转载&#xff1a;http://t.csdn.cn/KtidI 文章目录 1. vue基础知识和原理1.1 初识Vue1.2 模板语法1.3 数据绑定1.4 el与data的两种写法1.5 Vue中的MVVM1.6 数据代理1.7 事件处理1.8 键盘事件1.9 计算属性1.10 监视属性1.11 绑定样式class样式style样式 1.12 条件渲染v-ifv-…

(论文翻译)PRUNING FILTER IN FILTER《滤波器中的剪枝滤波器》

公式不清楚的地方请对照英文原文进行查看&#xff1a;原文链接 ABSTRACT 剪枝已成为现代神经网络压缩和加速的一种非常有效的技术。现有的剪枝方法可分为两大类:滤波器剪枝(FP)和权重剪枝(WP)。与WP相比&#xff0c;FP在硬件兼容性方面胜出&#xff0c;但在压缩比方面失败。为了…

海外APP外包开发第三方支付集成

APP开发过程中有收费功能时就需要集成第三方支付&#xff0c;相比传统的信用卡支付&#xff0c;第三方支付极大的提高了用户的支付便捷度&#xff0c;也推广了第三方支付的使用范围。海外有哪些支付渠道以及如何集成&#xff0c;今天和大家分享这方面的知识&#xff0c;希望对大…

微信小程序canvas生成图片并保存

需求&#xff1a; 做一个类似下图的功能。图片内容是动态的&#xff0c;用canvas画出来&#xff0c;生成临时图片&#xff0c;再保存。 实现&#xff1a; <view class"canvasBox"><canvas canvas-id"myCanvas" class"myCanvas">&l…

Burp的JS API接口过滤插件

Burp的JS API接口过滤插件 过滤js文件中的接口信息&#xff0c;并显示接口内容在js文件中的上下文。从js文件中过滤你需要的敏感信息&#xff0c;且支持在配置文件中自定义检出规则。完全被动检测&#xff0c;不会有任何主动请求行为。防止不可控请求的产生。

前端js react vue怎么实现在线预览doc文档

先说结论&#xff1a; 目前在纯前端层面没有很好的方案&#xff0c;基本都需要服务端的介入。 1.方案一&#xff1a;使用view.officeapps 优点&#xff1a;简单易用&#xff0c;无需配置 缺点&#xff1a;文档需要支持外网访问&#xff0c;且文档会是公开可见的&#xff0c…

skywalking java agent集成

目录 概述 裸机集成 docker集成 k8s集成 高级特性 Trace api Logback traceId协同 跨线程trace 附录 Agent参数 本地缓存队列参数 是否显示Sql参数 其他参数 概述 java 应用skywalking集成主要以java agent形式接入。 官方详细文档点击skywalking-java集成查看。…

负载均衡的知识点

目录 1.负载均衡是什么 2.负载均衡的分类 客户端负载均衡&#xff1a; 服务端负载均衡&#xff1a; 软件实现&#xff1a;根据OSI模型可以分为四层负载均衡和七层负载均衡 硬件实现&#xff1a; 附1&#xff1a;客户端和服务端&#xff1a; 附2&#xff1a;OSI…

备战秋招 | 笔试强训

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、使用printf函数打印一个double类型的数据&#xff0c;要求&#xff1a;输出为10进制&#xff0c;输出左对齐30个字符&#xff0c;4位精度。以下哪个选项是正确的&#xff1f; A. %-30.4e B. %4.…

基于DETR的人脸伪装检测

基于DETR的人脸伪装检测 前言前提条件实验环境项目地址LinuxWindows DETR训练自己的数据集修改models/detr.py中的参数进行训练进行预测 相关资源免费获取参考 前言 本文是个人使用DETR训练自己的COCO格式数据集的应用案例&#xff0c;由于水平有限&#xff0c;难免出现错漏&am…

​python接口自动化(二十八)--html测试 报告——下(详解) ​

简介 五一小长假已经结束了&#xff0c;想必大家都吃饱喝足玩好了&#xff0c;那就继续学习吧。一天不学习&#xff0c;自己知道&#xff1b;两天不学习&#xff0c;对手知道&#xff1b;三天不学习&#xff0c;大家知道&#xff1b;一周不学习&#xff0c;智商输给猪。好了开个…

excel怎么样将某列所有单元格中文本的非中文字符或数字或字母全部删除?

目录 1. 简述2. 函数功能及参数介绍&#xff08;1&#xff09;功能&#xff08;2&#xff09;参数介绍 3. 完整VBA代码4. 宏代码使用方法5. 效果图 1. 简述 当我们要处理大量行数的excel数据时候&#xff0c;有时某列中有些行中的单元格内容中含有我们不想要的部分&#xff08…

功率开关集成电路TWH8751路灯自动控制器/双D触发器CD4013路灯控制器电路设计

采用功率开关集成电路TWH8751的路灯自动控制器 本例介绍的光控路灯&#xff0c;在白天不工作&#xff0c;夜晚能自动点亮&#xff0c;可用于街道或农村场院等场合 。 一、电路工作原理 电路原理如图 19 所示。 该光控路灯电路由电源电路和光控电路组成&#xff0c;如图所示…

Latch up (闩锁效应)

Latch-up latch up 是指cmos晶片中, 在电源power VDD和地线GND(VSS)之间由于寄生的PNP和NPN双极性BJT(Bipolar Junction Transistors)相互影响而产生的一低阻抗通路, 它的存在会使VDD和GND之间产生大电流。    In the simplest way, the latch-up issue can be defined as a …