Java设计模式—组合模式(Composite Pattern)

组合模式(Composite),将对象组合成树形结构以表示'部分-整体'的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

java 复制代码
public class CompositeTest {
    public static void main(String[] args){
        // 创建主菜单
        MenuComponent mainMenu = new Menu("Insert");
        // 创建子菜单
        MenuComponent subMenu = new Menu("Chart");
        // 创建菜单项
        MenuComponent element = new MenuItem("On This Sheet");
        
        // 将子菜单添加到主菜单中
        mainMenu.addMenuElement(subMenu);
        // 将菜单项添加到子菜单中
        subMenu.addMenuElement(element);
        
        // 打印菜单结构
        printMenus(mainMenu);
    }
    
    private static void printMenus(MenuComponent ifile){
        // 打印当前菜单的名称
        ifile.printName();
        // 获取当前菜单的子元素列表
        List<MenuComponent> children = ifile.getElement();

        // 如果子元素列表为空,则直接返回
        if(children == null) return;
        
        // 遍历子元素列表,递归打印每个子元素的名称
        for(MenuComponent element : children){
            printMenus(element);
        }
    }
}
java 复制代码
public class Menu extends MenuComponent{
    private List<MenuComponent> elementList;

    public Menu(String name){
        this.name = name;
        this.elementList = new ArrayList<>();
    }

    public boolean addMenuElement(MenuComponent element){
        return elementList.add(element);
    }

    public boolean removeMenuElement(MenuComponent element){
        return elementList.remove(element);
    }

    public List<MenuComponent> getElement(){
        return elementList;
    }
}
java 复制代码
public class MenuItem extends MenuComponent{
    public MenuItem(String name){
        this.name = name;
    }

    public boolean addMenuElement(MenuComponent element){
        return false;
    }

    public boolean removeMenuElement(MenuComponent element){
        return false;
    }

    public List<MenuComponent> getElement(){
        return null;
    }
}
java 复制代码
public abstract class MenuComponent {
    protected String name;

    public void printName(){
        System.out.println(name);
    }

    public abstract boolean addMenuElement(MenuComponent element);

    public abstract List<MenuComponent> getElement();
}

MenuComponent 抽象类:定义了菜单组件的基本行为,包括打印名称和管理子元素的方法。

Menu 类:表示菜单,可以包含其他菜单或菜单项。

MenuItem 类:表示菜单中的一个具体项。

CompositeTest 类:包含了 main 方法,用于测试组合模式的实现。

CompositeTest 类中,main 方法创建了一个主菜单、一个子菜单以及一个菜单项,并将它们按照一定的结构添加到了一起。然后调用 printMenus 方法打印整个菜单的结构。

Menu 类表示菜单,它继承自 MenuComponent 抽象类,并实现了该抽象类中的抽象方法。Menu 类中包含一个 elementList 成员变量,用于存储菜单中的子元素(即菜单或菜单项)。它提供了添加和移除子元素的方法,并实现了抽象方法 getElement 来获取子元素列表。

MenuComponent 抽象类定义了菜单组件的基本行为,包括打印名称和管理子元素的方法。它有一个 name 成员变量表示菜单组件的名称,并定义了一个抽象方法 addMenuElement 用于添加子元素,以及一个抽象方法 getElement 用于获取子元素列表。

MenuItem 类表示菜单中的一个具体项,它继承自 MenuComponent 抽象类,并实现了该抽象类中的抽象方法。由于菜单项不包含其他子元素,因此 addMenuElementremoveMenuElementgetElement 方法的实现都返回了相应的默认值。

何时使用组合模式

当你发现需求中是体现部分与整体层次的结构时 ,以及你 希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时, 就应该考虑用组合模式了。" Java开发窗体用的容器控件java.awt.Container,它继承于java.awt.Component,就有add方法和remove方法,所以在它上面增加控件,比如Button、Label、Checkbox等控件,就变成很自然的事情,这就是典型的组合模式的应用。

相关推荐
会员源码网1 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java
孔明click332 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·sa-token·开源·springboot·登录·权限认证
程序猿阿越2 小时前
Kafka4源码(二)创建Topic
java·后端·源码阅读
悟空码字2 小时前
Spring Boot 整合 MongoDB 最佳实践:CRUD、分页、事务、索引全覆盖
java·spring boot·后端
省长2 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·后端·开源
NE_STOP3 小时前
MyBatis-动态sql与高级映射
java
后端AI实验室3 小时前
我把同一个需求分别交给初级程序员、高级程序员和AI,结果让我沉默了
java·ai
sTone873753 小时前
web后端开发概念: VO 和 PO
java·后端·架构
在西安放羊的牛油果3 小时前
我把 2000 行下单代码,重构成了一套交易前端架构
前端·设计模式·架构
SimonKing4 小时前
JetBrains+Qoder变身Agentic 编码平台,媲美Cursor、Trae等AI编程平台
java·后端·程序员