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

快速通过简单代码了解装饰模式

装饰模式简单实现

装饰模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。以下是一个简单的 Java 实现示例,模拟咖啡店中咖啡的装饰过程。

/**
 * 抽象组件类,代表饮品的基类。
 * 所有具体的饮品和装饰器都将基于此类进行扩展。
 */
// 抽象组件:饮品
abstract class Beverage {
    // 饮品的描述信息,默认值为 "Unknown Beverage"
    String description = "Unknown Beverage";

    /**
     * 获取饮品的描述信息。
     * @return 饮品的描述字符串
     */
    public String getDescription() {
        // 返回饮品的描述信息
        return description;
    }

    /**
     * 抽象方法,用于计算饮品的价格。
     * 具体的饮品子类需要实现此方法来提供具体的价格计算逻辑。
     * @return 饮品的价格
     */
    public abstract double cost();
}
/**
 * 具体组件类,代表浓缩咖啡饮品,继承自 Beverage 抽象类。
 * 该类实现了浓缩咖啡的基本属性和价格计算方法。
 */
// 具体组件:浓缩咖啡
class Espresso extends Beverage {
    /**
     * 构造函数,用于初始化浓缩咖啡的描述信息。
     * 调用该构造函数后,浓缩咖啡的描述将被设置为 "Espresso"。
     */
    public Espresso() {
        // 将饮品的描述设置为浓缩咖啡
        description = "Espresso";
    }

    /**
     * 重写父类的 cost 方法,用于计算浓缩咖啡的价格。
     * @return 浓缩咖啡的价格,固定为 2.0 元。
     */
    @Override
    public double cost() {
        // 返回浓缩咖啡的价格
        return 2.0;
    }
}
/**
 * 具体组件类,代表拿铁咖啡,继承自 Beverage 抽象类。
 * 该类实现了拿铁咖啡的基本属性和价格计算方法。
 */
class Latte extends Beverage {
    /**
     * 构造函数,用于初始化拿铁咖啡的描述信息。
     * 调用该构造函数后,拿铁咖啡的描述将被设置为 "Latte"。
     */
    public Latte() {
        // 将饮品的描述设置为拿铁
        description = "Latte";
    }

    /**
     * 重写父类的 cost 方法,用于计算拿铁咖啡的价格。
     * @return 拿铁咖啡的价格,固定为 2.5 元。
     */
    @Override
    public double cost() {
        // 返回拿铁的价格
        return 2.5;
    }
}
/**
 * 抽象装饰器类:调料
 * 该类继承自 Beverage 抽象类,用于装饰具体的饮品。
 * 所有具体的调料装饰器都应继承此类,并实现具体的装饰逻辑。
 */
// 抽象装饰器:调料
abstract class CondimentDecorator extends Beverage {
    /**
     * 抽象方法,用于获取添加调料后的饮品描述。
     * 具体的调料装饰器需要实现此方法,以返回包含调料信息的完整描述。
     * @return 添加调料后的饮品描述
     */
    public abstract String getDescription();
}
/**
 * 具体装饰器类,用于为饮品添加糖调料。
 * 该类继承自 CondimentDecorator 抽象类,用于扩展 Beverage 对象的功能。
 */
// 具体装饰器:糖
class Sugar extends CondimentDecorator {
    // 被装饰的饮品对象
    Beverage beverage;

    /**
     * 构造函数,接收一个 Beverage 对象作为参数。
     * 用于初始化当前装饰器所装饰的饮品对象。
     * @param beverage 被装饰的饮品对象
     */
    public Sugar(Beverage beverage) {
        // 将传入的饮品对象赋值给成员变量
        this.beverage = beverage;
    }

    /**
     * 重写 getDescription 方法,用于获取添加糖后的饮品描述。
     * 在原饮品描述的基础上,添加糖的描述。
     * @return 添加糖后的饮品完整描述
     */
    @Override
    public String getDescription() {
        // 拼接原饮品描述和糖的描述
        return beverage.getDescription() + ", Sugar";
    }

    /**
     * 重写 cost 方法,用于计算添加糖后的饮品价格。
     * 在原饮品价格的基础上,加上糖的价格。
     * @return 添加糖后的饮品总价格
     */
    @Override
    public double cost() {
        // 计算原饮品价格加上糖的价格
        return beverage.cost() + 0.2;
    }
}
/**
 * 具体装饰器类,用于为饮品添加牛奶调料。
 * 该类继承自 CondimentDecorator 抽象类,实现了具体的装饰逻辑。
 */
// 具体装饰器:牛奶
class Milk extends CondimentDecorator {
    // 被装饰的饮品对象
    Beverage beverage;

    /**
     * 构造函数,用于初始化 Milk 装饰器。
     * @param beverage 被装饰的饮品对象
     */
    public Milk(Beverage beverage) {
        // 保存被装饰的饮品对象
        this.beverage = beverage;
    }

    /**
     * 重写父类的 getDescription 方法,用于获取添加牛奶后的饮品描述。
     * @return 添加牛奶后的饮品描述
     */
    @Override
    public String getDescription() {
        // 在原饮品描述后添加牛奶信息
        return beverage.getDescription() + ", Milk";
    }

    /**
     * 重写父类的 cost 方法,用于计算添加牛奶后的饮品价格。
     * @return 添加牛奶后的饮品价格
     */
    @Override
    public double cost() {
        // 原饮品价格加上牛奶的价格
        return beverage.cost() + 0.5;
    }
}
/**
 * 具体装饰器类:摩卡,用于为饮品添加摩卡调料。
 * 该类继承自 CondimentDecorator 抽象类,实现了为饮品添加摩卡风味的功能。
 */
// 具体装饰器类:摩卡
class Mocha extends CondimentDecorator {
    // 持有被装饰的 Beverage 对象的引用
    Beverage beverage;

    /**
     * 构造函数,用于初始化 Mocha 装饰器。
     * @param beverage 被装饰的饮品对象,即要添加摩卡调料的饮品。
     */
    public Mocha(Beverage beverage) {
        // 将传入的饮品对象赋值给成员变量,以便后续操作
        this.beverage = beverage;
    }

    /**
     * 重写 getDescription 方法,用于获取添加摩卡后的饮品描述。
     * @return 拼接了摩卡描述后的完整饮品描述。
     */
    @Override
    public String getDescription() {
        // 在原饮品描述后面添加 ", Mocha" 来表示添加了摩卡调料
        return beverage.getDescription() + ", Mocha";
    }

    /**
     * 重写 cost 方法,用于计算添加摩卡后的饮品价格。
     * @return 原饮品价格加上摩卡调料的价格。
     */
    @Override
    public double cost() {
        // 原饮品价格加上摩卡调料的价格,这里摩卡调料价格固定为 0.5
        return beverage.cost() + 0.5;
    }
}
// 测试类
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 点一杯浓缩咖啡
        Beverage espresso = new Espresso();
        System.out.println(espresso.getDescription() + " 价格: $" + espresso.cost());

        // 给浓缩咖啡加牛奶和糖
        Beverage decoratedEspresso = new Sugar(new Milk(espresso));
        System.out.println(decoratedEspresso.getDescription() + " 价格: $" + decoratedEspresso.cost());

        // 再给加了牛奶的浓缩咖啡加摩卡
        decoratedEspresso = new Mocha(decoratedEspresso);
        System.out.println(decoratedEspresso.getDescription() + " 价格: $" + decoratedEspresso.cost());

        // 点一杯拿铁
        Beverage latte = new Latte();
        System.out.println(latte.getDescription() + " 价格: $" + latte.cost());

        // 给拿铁加牛奶
        Beverage decoratedLatte = new Milk(latte);
        System.out.println(decoratedLatte.getDescription() + " 价格: $" + decoratedLatte.cost());
    }
}

应用场景

  1. 图形界面组件:在 GUI 编程中,常常需要为组件添加额外的功能,如边框、滚动条、阴影等。可以使用装饰模式,通过装饰器为组件动态添加这些功能,而不需要修改组件的原始代码。
  2. 文件流处理:在 Java 的 I/O 流中,使用了装饰模式。例如,FileInputStream 是一个基本的输入流,而 BufferedInputStream 是一个装饰器,它为 FileInputStream 提供了缓冲功能,提高了读取效率。
  3. 权限验证:在系统中,对于不同的操作可能需要不同的权限验证。可以使用装饰模式,为基本的操作类添加不同的权限验证装饰器,动态地为操作添加权限验证功能。
  4. 日志记录:在方法执行前后添加日志记录功能,可以使用装饰模式。通过装饰器在不修改原有方法的基础上,为方法添加日志记录的功能。

相关文章:

  • 在Unity中,如果物体上的脚本丢失,可以通过编写一个自定义编辑器脚本来查找并删除这些丢失的组件
  • DeepSeek 教我 C++ (7) :常见的一些未定义UB
  • 基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(一)
  • 嵌入式硬件篇---TOF陀螺仪SPI液晶屏
  • Xorg内存管理机制深度解析
  • P1025 [NOIP 2001 提高组] 数的划分(DFS)
  • 【Linux】:HTTP协议
  • Spring RestTemplate修仙指南:从HTTP萌新到请求大能的终极奥义
  • 【VS Code】为什么vscode已经关闭,http://localhost:5173/还可以打开或项目还在运行,端口被占用
  • 软件工程面试题(三十二)
  • 如何计算卷积的复杂度、卷积层的参数量
  • 基于springboot+vue的漫画天堂网
  • frp内网穿透零基础详细教程
  • 03.31-04.06 论文速递 聚焦具身智能、复杂场景渲染、电影级对话生成等五大前沿领域
  • 如何解决uniapp打包安卓只出现功能栏而无数据的问题
  • 优雅实现级联选择器:CascadeSelect 类设计与实现
  • 第4课:列表渲染与条件渲染
  • Diffusion Policy Visuomotor Policy Learning via Action Diffusion官方项目解读(二)(2)
  • Java 集合框架与 Stream 流深入剖析(重点详细讲解)
  • langchain实现基于语义分块的文档处理技术semantic-chunker
  • 营销型网站建设企业/淘数据
  • 物流公司网站建设/郑州网站设计有哪些
  • 做玉的网站/网站排名怎么搜索靠前
  • 行业协会网站建设的目的/seo搜索引擎优化教程
  • 网站建设背景及目的/农产品品牌推广方案
  • 沙市网站建设/免费b2b信息发布网站