10 设计模式之装饰模式

news/2024/12/4 4:25:06/

一、什么是装饰模式

1.装饰模式(Decorator Pattern)

        是一种结构型设计模式用于动态地向对象添加新的功能,而无需修改其原始代码。它通过创建一系列装饰类,将功能封装在一个对象中,从而实现功能的灵活扩展。

2.核心思想:

        在不改变对象本身的情况下,通过包装(组合)的方式,动态地叠加或增强对象的行为。


二、装饰模式的结构

装饰模式包含以下几个关键角色:

  1. Component(抽象组件):定义了对象的接口,具体组件和装饰器都实现该接口。
  2. ConcreteComponent(具体组件):实现了组件接口,表示被装饰的对象。
  3. Decorator(抽象装饰器):实现组件接口,内部持有一个组件实例(即被装饰对象的引用)。
  4. ConcreteDecorator(具体装饰器):继承抽象装饰器,实现具体的功能扩展。

三、装饰模式的优缺点

优点:

  1. 符合开闭原则:无需修改已有代码即可扩展新功能。
  2. 灵活组合功能:通过装饰器类的嵌套,可以动态叠加不同的功能。
  3. 易于维护:功能模块化,扩展性强。

缺点:

  1. 增加了系统的复杂性,可能出现过多的装饰器类。
  2. 对于深度嵌套的装饰器链,调试和排查问题可能较为困难。

四、装饰模式的实现案例

        我们以一个制作咖啡的场景为例,展示如何使用装饰模式动态叠加功能。

1. 定义组件接口

java">// 抽象组件:定义了咖啡的接口
interface Coffee {String getDescription(); // 获取描述double cost();           // 获取价格
}

2. 定义具体组件

java">// 具体组件:浓缩咖啡
class EspressoCoffee implements Coffee {@Overridepublic String getDescription() {return "浓缩咖啡";}@Overridepublic double cost() {return 5; // 浓缩咖啡的价格}
}// 具体组件:美式咖啡
class AmericanoCoffee implements Coffee {@Overridepublic String getDescription() {return "美式咖啡";}@Overridepublic double cost() {return 8; // 美式咖啡的价格}
}

3. 定义抽象装饰器

java">// 抽象装饰器:实现 Coffee 接口并组合一个 Coffee 实例
abstract class Decorator implements Coffee {protected Coffee coffee; // 被装饰对象public Decorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String getDescription() {return coffee.getDescription(); // 调用被装饰对象的方法}@Overridepublic double cost() {return coffee.cost();}
}

4. 定义具体装饰器

java">// 具体装饰器:添加牛奶
class MilkDecorator extends Decorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return super.getDescription() + " 加奶";}@Overridepublic double cost() {return super.cost() + 2; // 牛奶价格为 2 元}
}// 具体装饰器:添加巧克力
class ChocolateDecorator extends Decorator {public ChocolateDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return super.getDescription() + " 加热巧";}@Overridepublic double cost() {return super.cost() + 3; // 巧克力价格为 3 元}
}// 具体装饰器:添加糖
class SugarDecorator extends Decorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return super.getDescription() + " 加糖";}@Overridepublic double cost() {return super.cost() + 1; // 糖价格为 1 元}
}

5. 测试装饰模式

java">public class TestDecorate {public static void main(String[] args) {// 基础咖啡Coffee coffee = new AmericanoCoffee();// 添加牛奶装饰coffee = new MilkDecorator(coffee);// 添加巧克力装饰coffee = new ChocolateDecorator(coffee);// 添加糖装饰coffee = new SugarDecorator(coffee);// 打印结果System.out.println("描述: " + coffee.getDescription());System.out.println("总价: " + coffee.cost() + " 元");}
}

五、输出结果

描述: 美式咖啡 加奶 加热巧 加糖 总价: 14.0 元


六、总结

  1. 装饰模式的核心在于“组合”:通过将对象嵌套包装,动态地叠加新功能。
  2. 典型使用场景:
    • 动态扩展类的功能,例如日志系统、IO流等。
    • 替代类继承,避免创建过多的子类。
  3. 注意事项:
    • 装饰器链条不宜过长,避免维护困难。
    • 选择合适的抽象层次,确保装饰器的功能明确。

        通过这个咖啡店的案例,我们学习了如何使用装饰模式动态地叠加功能,轻松实现了个性化的饮品搭配。装饰模式不仅提高了代码的灵活性,还能让程序更具扩展性,是一个非常实用的设计模式


http://www.ppmy.cn/news/1552178.html

相关文章

在1~n中、找出能同时满足用3除余2,用5除余3,用7除余2的所有整数。:JAVA

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 在1~n中、找出能同时满足用3除余2,用5除余3,用7除余2的所有整数。 输入描述: 输入一行,包含一个正整数n ,n在100000以内 输出描述:…

UICollectionView在xcode16编译闪退问题

使用xcode15运行工程,控制台会出现如下提示: Expected dequeued view to be returned to the collection view in preparation for display. When the collection views data source is asked to provide a view for a given index path, ensure that a …

YoloV10-yaml文件理解

最近在学习和尝试改进yolov结记录一下原始代码的理解,希望大佬指正.10,在这里总 [1] 论文:https://arxiv.org/abs/2405.14458 [2] 代码:GitHub - THU-MIG/yolov10: YOLOv10: Real-Time End-to-End Object Detection [NeurIPS 2024] YOLOv10的新特性 1. 无…

The selected directory is not a valid home for Go SDK

在idea里配置go语言的环境时,选择go语言的安装目录,一直提示这个 The selected directory is not a valid home for Go SDK后来查了一下,发现原来idea识别不出来 需要改一下配置文件,找到go环境的安装目录,我是默认安…

基于SSM超市商品管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档(1万字以上)开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统:Window操作系统 2、开发工具:IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

【论文阅读】 Learning to Upsample by Learning to Sample

论文结构目录 一、之前的上采样器二、DySample概述三、不同上采样器比较四、整体架构五、设计过程(1)初步设计(2)第一次修改(3)第二次修改(4)第三次修改 六、DySample四种变体七、复…

什么是sfp,onu,​为什么PON(​俗称“光猫”​)模块使用SC光纤接口

在现代网络设备中,我们经常会看到SFP或SFP接口的身影,这些接口有时被简称为光口,但这个称呼并不严谨。有些厂商则称之为多功能口或多用途口,然而这对于不了解的人来说可能还是一头雾水。SFP,即Small Form-Factor Plugg…

hint: Updates were rejected because the tip of your current branch is behind!

问题 本地仓库往远段仓库推代码时候提示: error: failed to push some refs to 192.168.2.1:java-base/java-cloud.git hint: Updates were rejected because the tip of your current branch is behind! refs/heads/master:refs/heads/master [rejected] (…