设计模式之组合模式

目录

定义

将对象组织成树状层次,通过统一的接口(如Component)管理所有节点(包括叶子节点和容器节点)。叶子节点处理基础操作,容器节点负责组合子节点并递归调用操作。‌

结构

适用场景

1、当系统需处理嵌套层级不固定的对象关系时,组合模式通过抽象接口统一叶子节点(基础单元)和容器节点(组合单元)

2、统一操作复杂对象集合(递归行为需求),对嵌套结构执行跨层级操作时,组合模式屏蔽节点类型差异,简化递归逻辑

3、简化客户端调用逻辑(接口一致性),当业务要求忽略节点差异时,组合模式提供透明性。

使用示例

以电商商品分类系统‌价格计算为例。

定义抽象构件

复制代码
/**
 * 抽象构件(商品节点接口)
 */
public interface ProductComponent {

    default void add(ProductComponent item) {
        throw new UnsupportedOperationException();
    }

    double getPrice(); // 统一方法:计算价格

    default void remove(ProductComponent item) {
        throw new UnsupportedOperationException();
    }

}

定义叶子节点

复制代码
/**
 * 叶子构件(具体商品)
 */
public class Product implements ProductComponent {

    @Getter
    private String name;

    private final double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public double getPrice() {
        return price;
    }

}

定义容器节点

复制代码
/**
 * 容器构件(商品分类)
 */
public class ProductCategory implements ProductComponent {

    @Getter
    private final String name;

    private final List<ProductComponent> items = new ArrayList<>();

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

    @Override
    public void add(ProductComponent item) {
        items.add(item);
    }

    @Override
    public void remove(ProductComponent item) {
        items.remove(item);
    }

    @Override
    public double getPrice() {
        double total = 0;
        for (ProductComponent item : items) {
            total += item.getPrice(); // 递归计算子节点价格
        }
        return total;
    }

}

测试

复制代码
public class Client {

    public static void main(String[] args) {
        ProductComponent electronics = new ProductCategory("电子产品");
        electronics.add(new Product("手机", 2999));
        electronics.add(new Product("耳机", 399));

        ProductComponent bundle = new ProductCategory("套装");
        bundle.add(new Product("充电器", 99));
        bundle.add(electronics); // 嵌套组合

        System.out.println(bundle.getPrice()); // 输出:3497
    }

}
相关推荐
xyouyuweizhu29 分钟前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
代码方舟40 分钟前
零信任架构实战:基于天远人企关联构建自动化供应链核心企业关联穿透与利益冲突审查网关
java·人工智能·架构·自动化
liyi_hz20081 小时前
O2OA(翱途) V10.1 即将发布|功能再升级,安全再加固,协同更高效!
java·javascript·windows·开源软件
骑着蜗牛撵大象3271 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
鬼手点金2 小时前
KV Cache 未必是一次性的:可编辑、可组合的“笔记”
java·人工智能·笔记·学习·自动化·1024程序员节
摇滚侠2 小时前
《On Java 中文版 基础卷》阅读笔记 初始化和清理 08
java·开发语言·笔记
海鸥-w2 小时前
Redis 配置与排错说明
java·数据库·redis·bootstrap
XiYang-DING2 小时前
P4009.和为K的子数组个数 & P5522.异或和为 k 的子数组个数
java·开发语言
TinyKey2 小时前
malloc_debug_notes
java
郭小李3 小时前
spring @PathVariable 注解用法
java·后端·spring