首页 > 其他分享 >装饰器模式 (Decorator Pattern)

装饰器模式 (Decorator Pattern)

时间:2024-11-22 10:45:35浏览次数:3  
标签:coffee Pattern getDescription Coffee public getCost 装饰 Decorator

装饰器模式 (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 {
    @Override
    public String getDescription() {
        return "Basic Coffee";
    }

    @Override
    public double getCost() {
        return 5.0;
    }
}

3. 创建装饰器抽象类
// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee; // 持有组件的引用

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

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

    @Override
    public double getCost() {
        return coffee.getCost();
    }
}

4. 创建具体装饰器
// 牛奶装饰器
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

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

    @Override
    public double getCost() {
        return coffee.getCost() + 1.5; // 牛奶价格
    }
}

// 糖装饰器
public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return coffee.getDescription() + ", Sugar";
    }

    @Override
    public 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. 避免继承扩展:用装饰器动态扩展功能而不引入过多的子类。

总结

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

标签:coffee,Pattern,getDescription,Coffee,public,getCost,装饰,Decorator
From: https://blog.csdn.net/qq_35861084/article/details/143960882

相关文章

  • 软件设计模式————(装饰模式)
    [实验任务一]:手机功能的升级用装饰模式模拟手机功能的升级过程:简单的手机(SimplePhone)在接收来电时,会发出声音提醒主人;而JarPhone除了声音还能振动;更高级的手机(ComplexPhone)除了声音、振动外,还有灯光闪烁提示。实验要求:1.提交类图; 2.提交源代码;packagetest11;publi......
  • Python-迭代器-生成器-装饰器
    迭代器、生成器和装饰器。迭代器用于遍历集合元素,如列表、字典和字符串。Iterator迭代器可迭代对象iterable惰性计算的序列反向迭代 迭代器有两个基本方法(实现了迭代器协议):__iter__()和__next__() iter()是Python中的一个内置函数,用于从可迭代对象(如列......
  • 11.6实验11:装饰模式
    [实验任务一]:手机功能的升级用装饰模式模拟手机功能的升级过程:简单的手机(SimplePhone)在接收来电时,会发出声音提醒主人;而JarPhone除了声音还能振动;更高级的手机(ComplexPhone)除了声音、振动外,还有灯光闪烁提示。实验要求:1. 提交类图;   2. 提交源代码;packagetest1......
  • 鸿蒙NEXT开发教程:浅谈@ComponentV2装饰器
    听说今天的广州车展上有一部分人已经看到华为汽车的最后一“界”,尊界超豪华大轿车,应该很快就要正式亮相,可以期待一波。在api12之后,鸿蒙系统推出一个V2版本的状态管理装饰器,不过目前还在开发试用状态,幽蓝君仔细研究了一下,今天跟大家做一个简单的介绍。幽蓝君对V2版本装饰器的总结......
  • IndexPatternService几个重写的方法
    @Override@Transactional(rollbackFor=Exception.class)publicAddIndexPatternResponsenewIndexPattern(AddIndexPatternRequestrequest){IndexPatternItemindexPatternItem=request.getIndexPatternItem();AddIndexPatternResponseresponse=newAddIndexPatt......
  • 在建筑装饰施工中,瓷砖铺设是非常重要的一环,特别是墙面和地面瓷砖的施工。为了确保质量
    在建筑装饰施工中,瓷砖铺设是非常重要的一环,特别是墙面和地面瓷砖的施工。为了确保质量与美观,瓷砖施工需要遵循一套明确的流程,且施工完毕后需要进行严格的验收。下面是瓷砖铺设的详细施工流程和验收流程:一、瓷砖施工流程1. 施工准备材料准备:包括瓷砖、瓷砖胶(粘合剂)、水泥砂浆......
  • Flask新手教程之- 视图函数的装饰器
    除了@app.route,Flask还支持其他装饰器,用于实现更复杂的功能。 示例:@app.before_request:在每个请求处理之前运行的函数。@app.after_request:在每个请求处理之后运行的函数。@app.teardown_request:在请求结束后运行的函数,用于清理工作。  实例:@app.before_requestd......
  • python装饰器decorator的应用
    python中的装饰器类似于java中的AOP切面编程的思想,下面通过demo教大家如何实现(1)一个最简单的装饰器demo1 #一个最简单的装饰器defmy_decorator(func):defwrapper():print("Somethingishappeningbeforethefunctioniscalled.")func()......
  • 【C#设计模式(3)——抽象工厂模式(Abstract Factory Pattern)】
    前言抽象工厂模式(AbstractFactoryPattern)运行结果代码//水果罐头接口publicinterfaceIFruitCan{voidCreateCan();}//苹果罐头类publicclassAppleCan:IFruitCan{stringName{get;set;}="苹果罐头";publicvoidCreateCan(){......
  • [1076] Clauses with the pattern "prep + which"
    Clauseswiththepattern"prep+which"areoftenusedtoaddadditionalinformationorclarifyarelationshipbetweentwopartsofasentence.Theseclausesareknownasrelativeclauses.Herearesomeexamplesandexplanations:Examples:In......