Java中的装饰器模式

news/2024/5/1 14:03:54

在Java中,装饰器模式允许我们动态地给对象添加新的行为或责任,而无需修改原有类。以下是一个简单的装饰器模式示例,我们将模拟一个咖啡销售系统,其中基础饮料类(Component)是Coffee,装饰器类(Decorator)用来添加额外的调料。

首先,定义抽象组件——基础咖啡接口:

// 抽象组件(Component)
public interface Coffee {double getCost(); // 获取咖啡价格String getDescription(); // 获取咖啡描述
}// 具体组件(ConcreteComponent)
public class SimpleCoffee implements Coffee {@Overridepublic double getCost() {return 1.0; // 基础咖啡的价格}@Overridepublic String getDescription() {return "Simple Coffee"; // 基础咖啡的描述}
}

接下来,创建装饰器接口:

// 装饰器接口(Decorator)
public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 维持对组件对象的引用public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic double getCost() {return coffee.getCost(); // 默认调用原始咖啡的价格}@Overridepublic String getDescription() {return coffee.getDescription(); // 默认调用原始咖啡的描述}
}

然后,我们创建几个具体的装饰器类,它们会附加额外的功能(比如添加糖、奶或者巧克力):

// 具体装饰器 - 添加糖
public class SugarDecorator extends CoffeeDecorator {private static final double SUGAR_COST = 0.25;public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + SUGAR_COST; // 在原始咖啡价格基础上增加糖的成本}@Overridepublic String getDescription() {return coffee.getDescription() + ", With Sugar"; // 更新描述信息}
}// 具体装饰器 - 添加牛奶
public class MilkDecorator extends CoffeeDecorator {private static final double MILK_COST = 0.5;public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + MILK_COST; // 在原始咖啡价格基础上增加牛奶的成本}@Overridepublic String getDescription() {return coffee.getDescription() + ", With Milk"; // 更新描述信息}
}// 可以继续定义其他装饰器,如ChocolateDecorator等...

最后,在客户端代码中,我们可以动态地构建不同口味的咖啡:

public class CoffeeShop {public static void main(String[] args) {Coffee simpleCoffee = new SimpleCoffee();System.out.println(simpleCoffee.getDescription() + " costs: " + simpleCoffee.getCost());Coffee coffeeWithSugar = new SugarDecorator(simpleCoffee);System.out.println(coffeeWithSugar.getDescription() + " costs: " + coffeeWithSugar.getCost());Coffee coffeeWithMilkAndSugar = new MilkDecorator(coffeeWithSugar);System.out.println(coffeeWithMilkAndSugar.getDescription() + " costs: " + coffeeWithMilkAndSugar.getCost());}
}

运行上述代码后,将会输出每种咖啡的描述和对应的价格,展示了如何通过装饰器模式动态地添加不同的调料并计算总成本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/11499.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

SV学习笔记(二)

接口 什么是接口? 接口 主要用作验证 ,国外有些团队会使用sv进行设计,那么接口就会用作设计。验证环境中,接口可以 使连接变得简洁而不易出错 。interface和module的使用性质很像, 可以定义端口,也可以定…

YUNBEE云贝-技术分享:PostgreSQL分区表

引言 PostgreSQL作为一款高度可扩展的企业级关系型数据库管理系统,其内置的分区表功能在处理大规模数据场景中扮演着重要角色。本文将深入探讨PostgreSQL分区表的实现逻辑、详细实验过程,并辅以分区表相关的视图查询、分区表维护及优化案例,…

手搓 Docker Image Creator(DIC)工具(02):预备知识

此节主要简单介绍一下 Docker、Dockerfile 的基本概念,Dockerfile 对的基本语法,Windows 和 macOS 下 Docker 桌面的安装,Docker 镜像的创建和运行测试等。 1 关于 Docker Docker 是一个开源的应用容器引擎,它允许开发者打包应用…

算法之美:堆排序原理剖析及应用案例分解实现

这段时间持续更新关于“二叉树”的专栏文章,关心的小伙伴们对于二叉树的基本原理已经有了初步的了解。接下来,我将会更深入地探究二叉树的原理,并且展示如何将这些原理应用到更广泛的场景中去。文章将延续前面文章的风格,尽量精炼…

【Go】十六、文件操作

文章目录 1、打开和关闭文件2、IO3、一次性读文件4、带缓冲区的读文件5、写入文件6、文件复制 1、打开和关闭文件 package main import("fmt""os" ) func main(){//打开文件:file,err : os.Open("d:/Test.txt");if err ! nil {//出错…

【讲解下Docker in Docker的原理与实践】

🌈个人主页:程序员不想敲代码啊🌈 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家🏆 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提…