Java设计模式超详解--组合设计模式(含uml图)

目录

一,初步说明

二,结合题目理解

三,题目练习

四,总结


一,初步说明

根据uml举个例子

这里的国际新闻和中国新闻显然是其他新闻的2个集合,整合一下我们发现:

国际新闻集合

中国新闻集合

Composit

那我们就把这里的国际新闻和中国新闻分别叫做其他新闻的组合,也就是这里的Composit

同时,我们发现,这里的新闻集合和具体地区的新闻我们都是用的一样的文件夹来进行保存,这是因为当用户在选择新闻的时候,首先他们是不想管新闻详细内容的,而是想先通过"标题"来进行筛选,一致的对待他们

Leaf

而这里的具体地区新闻就是Leaf

Component

最后我们引入了Component对以上组合和叶子进行统一管理

所以通过以上解释,相信大家也明白了为什么说组合设计模式是树形的:

二,结合题目理解

题目

组合设计模式: MenuItem 类是新闻菜单的叶子节点,print()方法简单地打印名称System.out.println(des);

CompositeMenu 是新闻的组合菜单,由MenuItem组成,print方法首先打印自己的名称,然后遍历调用子节点的print()方法

MenuComponent 是MenuItem 和CompositeMenu 共有的父类,des数据源是新闻菜单的名称;

以下是测试类,请补充其他类

java 复制代码
public class Main {

    

    public static void main(String[] args){

        MenuComponent news=new CompositeMenu("news");

        CompositeMenu chinaNews=new CompositeMenu("chinaNews");

        MenuComponent jpnNews=new MenuItem("jpnNews");

        MenuComponent gzNews=new MenuItem("GuiZhouNews");

        MenuComponent gdNews=new MenuItem("GuangDongNews");

        chinaNews.addComponent(gzNews);

        chinaNews.addComponent(gdNews);

        news.addComponent(chinaNews);

        news.addComponent(jpnNews);

        news.print();



    }

}

uml图:

代码:

java 复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * 抽象菜单组件(组合模式的核心抽象层)
 * 定义了叶子节点(MenuItem)和组合节点(CompositeMenu)的公共行为规范
 * 包含菜单名称属性、获取/设置名称的方法、抽象打印方法、默认的添加子组件方法
 */
abstract class MenuComponent {
    // 菜单组件的名称描述(如"news"、"chinaNews"、"GuiZhouNews")
    String des = "";

    /**
     * 获取菜单组件的名称
     * @return 菜单名称字符串
     */
    public String getDes() {
        return des;
    }

    /**
     * 设置菜单组件的名称
     * @param des 要设置的菜单名称
     */
    public void setDes(String des) {
        this.des = des;
    }

    /**
     * 构造方法:初始化菜单组件的名称
     * @param s 菜单名称
     */
    public MenuComponent(String s) {
        this.des = s;
    }

    /**
     * 抽象打印方法(组合模式的核心行为)
     * 要求所有子类必须实现自己的打印逻辑:
     * - 叶子节点(MenuItem):仅打印自身名称
     * - 组合节点(CompositeMenu):打印自身名称 + 递归打印所有子节点
     */
    public abstract void print();

    /**
     * 添加子组件的默认实现
     * 叶子节点(MenuItem)不支持添加子组件,因此默认抛出不支持操作异常
     * 组合节点(CompositeMenu)会重写此方法,实现添加子组件的逻辑
     * @param c 要添加的子菜单组件
     * @throws UnsupportedOperationException 不支持添加子组件时抛出
     */
    public void addComponent(MenuComponent c) {
        throw new UnsupportedOperationException("不能添加子节点");
    }

}

/**
 * 菜单叶子节点(MenuItem):表示不可再拆分的单个菜单(如"GuiZhouNews"、"jpnNews")
 * 继承自MenuComponent,实现抽象的print()方法,仅打印自身名称
 */
class MenuItem extends MenuComponent {
    /**
     * 构造方法:调用父类构造方法初始化菜单名称
     * @param s 叶子菜单的名称(如"GuiZhouNews")
     */
    public MenuItem(String s) {
        // 调用父类MenuComponent的构造方法,初始化des属性
        super(s);
    }

    /**
     * 实现父类的抽象print()方法
     * 叶子节点的打印逻辑:直接输出自身的菜单名称
     */
    @Override // 注解:明确表示重写父类的抽象方法
    public void print() {
        // 打印当前叶子菜单的名称(des属性)
        System.out.println(des);
    }
}

/**
 * 菜单组合节点(CompositeMenu):表示可包含子菜单的组合菜单(如"news"、"chinaNews")
 * 继承自MenuComponent,重写addComponent()和print()方法,支持子组件管理和递归打印
 */
class CompositeMenu extends MenuComponent {
    // 存储子菜单组件的集合(可以是MenuItem或CompositeMenu,体现多态)
    private List<MenuComponent> compositeMenu = new ArrayList<MenuComponent>();

    /**
     * 构造方法:调用父类构造方法初始化组合菜单的名称
     * @param s 组合菜单的名称(如"news"、"chinaNews")
     */
    public CompositeMenu(String s) {
        // 调用父类MenuComponent的构造方法,初始化des属性
        super(s);
    }

    /**
     * 重写父类的addComponent()方法
     * 组合节点支持添加子组件,将子菜单存入集合中
     * @param c 要添加的子菜单组件(可以是MenuItem或CompositeMenu)
     */
    @Override // 注解:重写父类的默认方法
    public void addComponent(MenuComponent c) {
        // 将子组件添加到集合中,实现组合菜单的子节点管理
        compositeMenu.add(c);
    }

    /**
     * 实现父类的抽象print()方法
     * 组合节点的打印逻辑:
     * 1. 先打印自身的菜单名称
     * 2. 遍历所有子组件,递归调用子组件的print()方法(多态特性)
     */
    @Override // 注解:重写父类的抽象方法
    public void print() {
        // 第一步:打印当前组合菜单的名称(如"news"、"chinaNews")
        System.out.println(des);
        // 第二步:遍历所有子组件,递归调用print()方法
        // 子组件可能是MenuItem(直接打印)或CompositeMenu(继续递归)
        for (MenuComponent i : compositeMenu) {
            // 多态调用:根据子组件的实际类型执行对应的print()方法
            i.print();
        }
    }

}

三,题目练习

采用组合设计模式实现价格计算: Part类是零件(叶子节点)零件的价格直接由构造方法传入;

Composite是组合件,由Componet组成,价格由子节点累计;

Componet是零件和组件共有的父类,des数据域是名称;

请完成Composite类和Part类提交

java 复制代码
import java.util.*;



abstract class Component {

    String des="";

    public String getDes() {

        return des;

    }

    public void setDes(String des) {

        this.des = des;

    }



    public Component(String s) {

        this.des = s;

    }



    public abstract  double  computerPrice();

    public void addComponent(Component c){

        throw new UnsupportedOperationException("不能添加子节点");

    }



}



//请完成Composite类和Part类提交





public class Main {

    

    public static void main(String[] args){

        Composite computer=new Composite("计算机");

        Part mouse=new Part(30,"鼠标");

        Part keyBoard=new Part(40,"键盘");

        Part screen=new Part(800,"显示器");

        computer.addComponent(mouse);

        computer.addComponent(keyBoard);

        computer.addComponent(screen);

        Composite box=new Composite("机箱");

        Part mainBoard=new Part(800,"主板");

        Part displayCard=new Part(500,"显卡");

        Part disk=new Part(400,"硬盘");

        box.addComponent(mainBoard);

        box.addComponent(displayCard);

        box.addComponent(disk);

        computer.addComponent(box);

        System.out.println(box.computerPrice());

        System.out.println(computer.computerPrice());

    }

}

uml图:

代码

java 复制代码
class Composite extends Component {
    private List<Component> component = new ArrayList<Component>();
    public Composite(String s){
        super(s);
    } 
    public void addComponent(Component c){
        component.add(c);
    }
    public double computerPrice(){
        double total=0.0;
        for(Component i:component){
            total+=i.computerPrice();
        }
        return total;
    }
}
class Part extends Component {
    private double num;
    public Part(double num,String s){
        super(s);
        this.num =num;
    }
     public double computerPrice(){
        return num; 
     }
}

四,总结

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

设计模式系列持续更新,欢迎关注博主~

希望对大家有用,祝您开心~(o゜▽゜)o☆,有问题欢迎交流,俺会改的✊

相关推荐
市场部需要一个软件开发岗位2 分钟前
JAVA开发常见安全问题:纵向越权
java·数据库·安全
历程里程碑15 分钟前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
程序员泠零澪回家种桔子34 分钟前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
CodeCaptain42 分钟前
nacos-2.3.2-OEM与nacos3.1.x的差异分析
java·经验分享·nacos·springcloud
Anastasiozzzz2 小时前
Java Lambda 揭秘:从匿名内部类到底层原理的深度解析
java·开发语言
骇客野人2 小时前
通过脚本推送Docker镜像
java·docker·容器
铁蛋AI编程实战2 小时前
通义千问 3.5 Turbo GGUF 量化版本地部署教程:4G 显存即可运行,数据永不泄露
java·人工智能·python
晚霞的不甘2 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
SunnyDays10112 小时前
使用 Java 冻结 Excel 行和列:完整指南
java·冻结excel行和列
摇滚侠2 小时前
在 SpringBoot 项目中,开发工具使用 IDEA,.idea 目录下的文件需要提交吗
java·spring boot·intellij-idea