【设计模式|结构型】组合模式(Composite Pattern)

背景

假设我们要设计一个餐厅菜单系统,菜单可以包含单个菜品和菜单套餐。每个菜品有自己的名称、价格和描述,而菜单套餐可以包含多个菜品和其他菜单套餐。

这时可以使用组合模式来设计这个餐厅菜单系统。

概述

组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示整体-部分层次结构。组合模式使得客户端可以统一处理单个对象以及对象组合,而无需区分它们的实际类型。该模式通过定义一组相同的接口,使得组合对象和叶子对象具有一致的行为。

示例一

首先,我们定义一个抽象的菜单项接口:

// 菜单项接口
public interface MenuItem {
    String getName();
    double getPrice();
    String getDescription();
}

然后,我们实现具体的菜品类和菜单套餐类:

// 菜品类
public class Dish implements MenuItem {
    private String name;
    private double price;
    private String description;

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

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

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

    @Override
    public String getDescription() {
        return description;
    }
}

// 菜单套餐类
public class MenuCombo implements MenuItem {
    private String name;
    private List<MenuItem> items = new ArrayList<>();

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

    public void addItem(MenuItem item) {
        items.add(item);
    }

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

    @Override
    public double getPrice() {
        double totalPrice = 0;
        for (MenuItem item : items) {
            totalPrice += item.getPrice();
        }
        return totalPrice;
    }

    @Override
    public String getDescription() {
        StringBuilder description = new StringBuilder();
        for (MenuItem item : items) {
            description.append(item.getName()).append(", ");
        }
        return description.toString();
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        // 创建菜品
        MenuItem dish1 = new Dish("鱼香肉丝", 20.0, "经典川菜");
        MenuItem dish2 = new Dish("宫保鸡丁", 18.0, "家常菜");
        MenuItem dish3 = new Dish("水煮鱼", 25.0, "川菜");

        // 创建菜单套餐
        MenuCombo combo1 = new MenuCombo("套餐1");
        combo1.addItem(dish1);
        combo1.addItem(dish2);

        MenuCombo combo2 = new MenuCombo("套餐2");
        combo2.addItem(dish3);
        combo2.addItem(combo1);

        // 计算总价格和描述
        double totalPrice = combo2.getPrice();
        String description = combo2.getDescription();

        // 打印结果
        System.out.println("总价格:" + totalPrice);
        System.out.println("描述:" + description);
    }
}

运行结果:

总价格:63.0
描述:水煮鱼, 鱼香肉丝, 宫保鸡丁,

示例二

一个常见的实际应用场景是图形绘制系统。假设你需要绘制一个复杂的图形,这个图形由多个形状组成,包括圆形、矩形、三角形等。你可以使用组合模式来表示这个图形,并统一对待各种形状。

以下是一个示例代码:

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

class Triangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制三角形");
    }
}

class ComplexShape implements Shape {
    private List<Shape> shapes = new ArrayList<>();

    public void addShape(Shape shape) {
        shapes.add(shape);
    }

    public void removeShape(Shape shape) {
        shapes.remove(shape);
    }

    @Override
    public void draw() {
        System.out.println("绘制复杂图形");
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape triangle = new Triangle();
        Shape complexShape = new ComplexShape();
        
        ((ComplexShape) complexShape).addShape(circle);
        ((ComplexShape) complexShape).addShape(triangle);
        
        complexShape.draw();
    }
}

输出结果:

绘制复杂图形

绘制圆形

绘制三角形

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值