当前位置: 首页 > news >正文

装饰器模式

装饰器模式:动态扩展类功能的设计艺术

一、装饰器模式的核心定义

装饰器模式(Decorator Pattern) 是一种结构型设计模式,它允许在不改变原有类结构和逻辑的前提下,通过 “包装” 的方式动态为对象添加新的功能。其核心思想是:用装饰器类包裹原始类,通过组合而非继承的方式扩展功能,既保留了原始类的完整性,又实现了功能的灵活增减。

简单来说,装饰器模式就像给礼物包装 —— 礼物(原始对象)本身不变,但通过不同的包装纸、丝带(装饰器),可以呈现出不同的效果(新增功能),且包装过程可叠加、可拆分。

二、装饰器模式的核心结构

装饰器模式包含四个关键角色,各角色职责明确、相互配合:

  1. 抽象组件(Component):定义原始对象和装饰器的共同接口 / 抽象类,是装饰器模式的基础,确保装饰器和原始对象可被统一对待。

  2. 具体组件(Concrete Component):抽象组件的实现类,即 “被装饰的原始对象”,包含核心业务逻辑。

  3. 抽象装饰器(Decorator):继承或实现抽象组件,内部持有一个抽象组件的引用(可指向原始对象或其他装饰器),并定义与抽象组件一致的接口,确保装饰器可嵌套。

  4. 具体装饰器(Concrete Decorator):抽象装饰器的实现类,负责为对象添加具体的新增功能,在调用原始组件方法的基础上,扩展额外逻辑。

结构示意图(简化):

Component(抽象组件)↑├───────┬───────┤ConcreteComponent(具体组件)  Decorator(抽象装饰器)↑ConcreteDecoratorA(具体装饰器A)ConcreteDecoratorB(具体装饰器B)

三、装饰器模式的代码实现(Java 示例)

以 “咖啡订单” 为例:基础咖啡(黑咖啡)是原始对象,可通过添加牛奶、糖等装饰器扩展功能,且支持多层装饰(如 “黑咖啡 + 牛奶 + 糖”)。

1. 抽象组件(Coffee)

定义咖啡的统一接口,包含核心方法(计算价格、描述):

public interface Coffee {// 计算价格double cost();// 描述咖啡信息String getDescription();}

2. 具体组件(BlackCoffee)

原始咖啡类,实现核心业务逻辑:

public class BlackCoffee implements Coffee {@Overridepublic double cost() {return 10.0; // 黑咖啡基础价格}@Overridepublic String getDescription() {return "黑咖啡";}}

3. 抽象装饰器(CoffeeDecorator)

持有 Coffee 引用,实现 Coffee 接口,确保装饰器与原始对象接口一致:

public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 持有被装饰的对象// 构造方法传入被装饰对象public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}// 委托给被装饰对象实现基础方法,具体装饰器可重写扩展@Overridepublic double cost() {return coffee.cost();}@Overridepublic String getDescription() {return coffee.getDescription();}}

4. 具体装饰器(MilkDecorator、SugarDecorator)

实现具体的扩展功能,在原始方法基础上添加额外逻辑:

// 牛奶装饰器public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}// 扩展价格:添加牛奶的费用@Overridepublic double cost() {return super.cost() + 3.0; // 牛奶价格3元}// 扩展描述:添加“加牛奶”信息@Overridepublic String getDescription() {return super.getDescription() + " + 牛奶";}}// 糖装饰器public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double cost() {return super.cost() + 1.5; // 糖价格1.5元}@Overridepublic String getDescription() {return super.getDescription() + " + 糖";}}

5. 客户端调用(测试代码)

通过嵌套装饰器动态扩展功能,支持灵活组合:

public class Client {public static void main(String[] args) {// 1. 点一杯纯黑咖啡Coffee coffee = new BlackCoffee();System.out.println(coffee.getDescription() + ",价格:" + coffee.cost() + "元");// 输出:黑咖啡,价格:10.0元// 2. 黑咖啡 + 牛奶coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + ",价格:" + coffee.cost() + "元");// 输出:黑咖啡 + 牛奶,价格:13.0元// 3. 黑咖啡 + 牛奶 + 糖(多层装饰)coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + ",价格:" + coffee.cost() + "元");// 输出:黑咖啡 + 牛奶 + 糖,价格:14.5元// 4. 单独黑咖啡 + 糖(灵活组合)Coffee coffee2 = new SugarDecorator(new BlackCoffee());System.out.println(coffee2.getDescription() + ",价格:" + coffee2.cost() + "元");// 输出:黑咖啡 + 糖,价格:11.5元}}

四、装饰器模式的核心优势

  1. 功能扩展灵活:无需修改原始类,通过新增装饰器即可扩展功能,符合 “开闭原则”(对扩展开放,对修改关闭)。

  2. 组合性强:支持多层装饰和灵活组合,可按需搭配功能(如 “牛奶 + 糖”“糖 + 牛奶” 效果一致,且可新增更多装饰器)。

  3. 替代继承:避免了类的多层继承导致的 “类爆炸” 问题(如 “黑咖啡加牛奶”“黑咖啡加糖”“黑咖啡加牛奶加糖” 无需创建多个子类)。

  4. 动态增减功能:运行时可通过添加 / 移除装饰器,动态改变对象的功能(如先点 “黑咖啡 + 牛奶”,后续可再加 “糖”)。

五、装饰器模式的应用场景

  1. 需要动态扩展对象功能:如 Java 的IO流InputStream/OutputStream)是装饰器模式的经典应用 ——FileInputStream是具体组件,BufferedInputStream(缓冲装饰)、DataInputStream(数据处理装饰)是具体装饰器,支持多层包装(如new BufferedInputStream(new FileInputStream("file.txt")))。

  2. 避免多层继承:如电商平台的商品折扣(基础商品 + 满减装饰 + 优惠券装饰 + 会员折扣装饰),无需为每种折扣组合创建子类。

  3. 功能可灵活组合:如编辑器的文本格式(普通文本 + 加粗装饰 + 斜体装饰 + 下划线装饰),支持任意组合格式。

六、使用注意事项

  1. 接口一致性:装饰器类必须与被装饰类实现相同的接口,否则无法嵌套使用。

  2. 避免过度装饰:多层装饰可能导致代码复杂度上升,需合理控制装饰层数。

  3. 区分核心功能与装饰功能:原始类应只包含核心业务逻辑,装饰类专注于扩展功能,避免职责混淆。

http://www.jsqmd.com/news/64367/

相关文章:

  • std function如何消除不同functor的类型和存储差别
  • 2025年靠谱的轮胎品牌哪家好?口碑好的轮胎品牌哪家好?官方精选可靠品牌指南
  • 2025年什么牌子的轮胎比较好:权威测评优质轮胎排行
  • 权重衰减
  • 2025年中国前五轮胎品牌:权威TOP10轮胎榜单发布
  • 完整教程:简析单目相机模型中的针孔模型
  • 完整教程:简析单目相机模型中的针孔模型
  • 理想L6更换轮胎推荐:2025年销量突破100万的胎压表现
  • 问界M8更换轮胎推荐:2025年效率提升80%的推荐
  • 题解 CF 2173 Div2
  • faster r cnn中的动量
  • 读大话数据结构的总结1
  • 车辆ID跟踪与车牌纠正分析
  • 需求的分层
  • 1pcs 3pcs是啥
  • 红旗HS6 PHEV更换轮胎推荐:2025年用户满意度高的方案
  • 12.5 程序员修炼之道:从小工到专家 第7章 在项目开始之前 - GENGAR
  • 理想L9更换轮胎推荐:2025年超500万用户力荐的组合
  • 小红书玩疯了!Ai像素级拆解提示词+Nano Banan Pro免费使用教程(附Api接入实战)
  • 2025.12.6日20:13-harsh无情的;粗糙的
  • 实验5
  • 2.2.STM32-新建工程 - 指南
  • 《软件需求》
  • 软件需求分析
  • 2026年网络安全展望:AI加速、攻击面扩张与专业化红队的未来
  • 创建图像分类器模型
  • 个人健康系统|健康管理|基于java+Android+微信小代码的个人健康平台设计与完成(源码+数据库+文档)
  • 接入Impala、Hive 的报表、BI、数据中台的国内厂商评价及接口框架
  • 完整教程:用Python识别图片中的文字(Tesseract OCR)
  • 完整教程:用Python识别图片中的文字(Tesseract OCR)