欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 装饰器模式 (Decorator Pattern)

装饰器模式 (Decorator Pattern)

2025/5/9 18:44:51 来源:https://blog.csdn.net/qq_35861084/article/details/143960882  浏览:    关键词:装饰器模式 (Decorator Pattern)

装饰器模式 (Decorator Pattern)

装饰器模式是一种 结构型设计模式,它允许动态地向对象添加新的功能,同时又不改变其结构。这种模式通过对象组合来实现,比通过继承扩展功能更加灵活。


原理

  1. 核心思想:通过将对象包装在一系列装饰器中,增强或修改对象的功能,而无需更改对象本身的代码。
  2. 适用场景
    • 希望动态地扩展一个类的功能,而不使用继承。
    • 需要为一个对象提供多种行为组合,且行为的数量动态变化。
  3. 参与角色
    • Component(抽象组件):定义一个对象接口,可以动态地为其添加职责。
    • ConcreteComponent(具体组件):实现抽象组件的类,是被装饰的对象。
    • Decorator(装饰器):实现抽象组件,并持有一个具体组件的引用。
    • ConcreteDecorator(具体装饰器):扩展装饰器,提供额外的功能。

优点

  1. 动态扩展功能:无需修改原始类和其他装饰器类即可扩展功能。
  2. 遵循开闭原则:通过添加新装饰器类来实现功能扩展。
  3. 灵活组合:装饰器可以任意组合使用。

缺点

  1. 复杂性增加:过多的装饰器可能导致系统变得复杂。
  2. 调试困难:在装饰器链中定位问题可能较为困难。

示例代码

场景描述

假设有一个咖啡订单系统,不同的咖啡可以加不同的调料(如牛奶、糖)。咖啡本身和调料的价格需要动态组合计算,且系统应具备良好的扩展性。


1. 定义抽象组件
// 抽象组件
public interface Coffee {String getDescription(); // 获取描述double getCost();        // 获取价格
}

2. 创建具体组件
// 具体组件:基础咖啡
public class BasicCoffee implements Coffee {@Overridepublic String getDescription() {return "Basic Coffee";}@Overridepublic double getCost() {return 5.0;}
}

3. 创建装饰器抽象类
// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {protected Coffee coffee; // 持有组件的引用public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String getDescription() {return coffee.getDescription();}@Overridepublic double getCost() {return coffee.getCost();}
}

4. 创建具体装饰器
// 牛奶装饰器
public class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Milk";}@Overridepublic double getCost() {return coffee.getCost() + 1.5; // 牛奶价格}
}// 糖装饰器
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Sugar";}@Overridepublic double getCost() {return coffee.getCost() + 0.5; // 糖价格}
}

5. 客户端代码
public class DecoratorPatternExample {public static void main(String[] args) {// 基础咖啡Coffee coffee = new BasicCoffee();System.out.println(coffee.getDescription() + " -> $" + coffee.getCost());// 加牛奶的咖啡coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " -> $" + coffee.getCost());// 加牛奶和糖的咖啡coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " -> $" + coffee.getCost());}
}

输出结果
Basic Coffee -> $5.0
Basic Coffee, Milk -> $6.5
Basic Coffee, Milk, Sugar -> $7.0

UML 类图

         +----------------+         +--------------------+|    Coffee      |<>------>|  CoffeeDecorator   |+----------------+         +--------------------+|+ getDescription()        |+ getDescription()  ||+ getCost()               |+ getCost()         |+----------------+         +--------------------+^                           ^|                           |+--------------------+         +--------------------+|   BasicCoffee      |         | MilkDecorator      |+--------------------+         +--------------------+|+ getDescription()  |         |+ getDescription()  ||+ getCost()         |         |+ getCost()         |+--------------------+         +--------------------+

使用场景

  1. 需要动态地增加功能:如图形编辑器中为图形对象添加功能(边框、阴影)。
  2. 功能组合的场景:如不同装饰效果的叠加。
  3. 避免继承扩展:用装饰器动态扩展功能而不引入过多的子类。

总结

  • 装饰器模式是一种灵活的设计模式,可以在运行时动态地为对象添加功能。
  • 它有效避免了类爆炸问题,特别适合需要灵活组合的场景。
  • 通过对象组合,装饰器模式实现了强大的扩展能力,符合 开闭原则

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词