装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给对象添加新的行为,而不改变其结构。以下是一个用 Java 实现的装饰器模式示例:

示例:咖啡店

假设你有一个咖啡店,咖啡有不同的类型(如 Espresso、Latte),并且可以添加不同的调料(如牛奶、糖、巧克力)。你希望能够动态地给咖啡添加这些调料。

代码实现

  1. 创建 Beverage 接口:这是所有饮料类的公共接口。
java 复制代码
public interface Beverage {
    String getDescription();
    double cost();
}
  1. 创建具体的饮料类:如 Espresso 和 Latte。
java 复制代码
public class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

public class Latte implements Beverage {
    @Override
    public String getDescription() {
        return "Latte";
    }

    @Override
    public double cost() {
        return 2.99;
    }
}
  1. 创建装饰器抽象类:所有的调料装饰器都需要继承这个类。
java 复制代码
public abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;

    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription();
    }

    @Override
    public double cost() {
        return beverage.cost();
    }
}
  1. 创建具体的装饰器类:如牛奶和巧克力。
java 复制代码
public class Milk extends CondimentDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.5;
    }
}

public class Chocolate extends CondimentDecorator {
    public Chocolate(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Chocolate";
    }

    @Override
    public double cost() {
        return beverage.cost() + 0.7;
    }
}
  1. 客户端代码:使用装饰器模式来创建饮料,并添加调料。
java 复制代码
public class CoffeeShop {
    public static void main(String[] args) {
        // 创建一个Espresso,不加任何调料
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        // 创建一个加牛奶的Latte
        Beverage latteWithMilk = new Milk(new Latte());
        System.out.println(latteWithMilk.getDescription() + " $" + latteWithMilk.cost());

        // 创建一个加牛奶和巧克力的Espresso
        Beverage espressoWithMilkAndChocolate = new Chocolate(new Milk(new Espresso()));
        System.out.println(espressoWithMilkAndChocolate.getDescription() + " $" + espressoWithMilkAndChocolate.cost());
    }
}

输出结果

plaintext 复制代码
Espresso $1.99
Latte, Milk $3.49
Espresso, Milk, Chocolate $3.19

这个例子展示了如何使用装饰器模式来动态地给对象添加功能。在这个例子中,每个调料(如牛奶和巧克力)都作为一个装饰器,通过组合的方式与基本饮料对象(如 Espresso 和 Latte)组合在一起,从而实现了功能的扩展。

相关推荐
超级大只老咪4 小时前
数组相邻元素比较的循环条件(Java竞赛考点)
java
小浣熊熊熊熊熊熊熊丶5 小时前
《Effective Java》第25条:限制源文件为单个顶级类
java·开发语言·effective java
毕设源码-钟学长5 小时前
【开题答辩全过程】以 公交管理系统为例,包含答辩的问题和答案
java·eclipse
啃火龙果的兔子5 小时前
JDK 安装配置
java·开发语言
星哥说事5 小时前
应用程序监控:Java 与 Web 应用的实践
java·开发语言
派大鑫wink5 小时前
【JAVA学习日志】SpringBoot 参数配置:从基础到实战,解锁灵活配置新姿势
java·spring boot·后端
xUxIAOrUIII5 小时前
【Spring Boot】控制器Controller方法
java·spring boot·后端
Dolphin_Home5 小时前
从理论到实战:图结构在仓库关联业务中的落地(小白→中级,附完整代码)
java·spring boot·后端·spring cloud·database·广度优先·图搜索算法
等....5 小时前
Miniconda使用
开发语言·python
zfj3215 小时前
go为什么设计成源码依赖,而不是二进制依赖
开发语言·后端·golang