目录

java设计模式——装饰者模式

定义: 装饰者模式是一种结构型设计模式,它允许动态地给对象添加新的功能,而不会改变其原有的结构。与继承不同,装饰者模式通过组合而不是继承来扩展对象的功能,这样可以有效地避免类爆炸问题(多个子类的冗余)。

在装饰者模式中,通常有以下几个关键角色:

抽象组件:定义对象的接口,可以是接口或抽象类。具体组件和装饰者都实现或继承该组件。

具体组件:实现抽象组件接口的具体类,它是被装饰的对象。

装饰者:实现抽象组件接口的类,内部维护一个抽象组件的引用,用于对被装饰对象进行扩展。

具体装饰者:继承装饰者并扩展其功能,可以为被装饰对象动态添加新功能。

优点

灵活性:通过组合而不是继承来扩展对象的功能,可以在运行时选择不同的装饰者动态组合对象。

遵循开闭原则:装饰者模式允许对功能进行扩展,而无需修改现有的代码。

减少子类的冗余:避免类层次的复杂性和继承的弊端。

缺点

复杂性增加:使用装饰者模式会增加系统中类的数量和对象的层次,增加理解和调试的难度。

难以维护:多个装饰者叠加时,调试可能变得困难,因为可能需要跟踪多个装饰者的行为。

实现示例

假设我们有一个咖啡店系统,每种咖啡有不同的类型(如普通咖啡、加牛奶的咖啡、加糖的咖啡等)。我们想要通过装饰者模式来灵活地添加配料,而不是为每种组合创建不同的类。

  1. 定义抽象组件 Beverage
java 复制代码
// 抽象组件
public abstract class Beverage {
    // 每种饮料都有一个描述和一个价格
    protected String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
  1. 定义具体组件 Coffee
java 复制代码
// 具体组件 - 咖啡
public class Coffee extends Beverage {

    public Coffee() {
        description = "Coffee";
    }

    @Override
    public double cost() {
        return 5.0; // 基本咖啡的价格
    }
}
  1. 定义装饰者 CondimentDecorator
java 复制代码
// 抽象装饰者 - 调料装饰器
public abstract class CondimentDecorator extends Beverage {
    // 强制要求具体装饰者必须实现 getDescription 方法
    public abstract String getDescription();
}
  1. 定义具体装饰者 MilkSugar
java 复制代码
// 具体装饰者 - 牛奶
public class Milk extends CondimentDecorator {
    // 被装饰的对象
    Beverage beverage;

    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

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

    @Override
    public double cost() {
        return 1.5 + beverage.cost(); // 牛奶的价格加上原始饮料的价格
    }
}

// 具体装饰者 - 糖
public class Sugar extends CondimentDecorator {
    // 被装饰的对象
    Beverage beverage;

    public Sugar(Beverage beverage) {
        this.beverage = beverage;
    }

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

    @Override
    public double cost() {
        return 0.5 + beverage.cost(); // 糖的价格加上原始饮料的价格
    }
}
  1. 测试装饰者模式
java 复制代码
public class CoffeeShop {
    public static void main(String[] args) {
        // 创建一杯基本的咖啡
        Beverage beverage = new Coffee();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        // 给咖啡加牛奶
        beverage = new Milk(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        // 给咖啡加牛奶和糖
        beverage = new Sugar(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
    }
}

输出结果:

java 复制代码
Coffee $5.0
Coffee, Milk $6.5
Coffee, Milk, Sugar $7.0
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
无名之逆13 分钟前
[特殊字符] Hyperlane 框架:高性能、灵活、易用的 Rust 微服务解决方案
运维·服务器·开发语言·数据库·后端·微服务·rust
SnXJi_23 分钟前
开源赋能,双驱协同:纷析云财务与进销存软件助力企业数字化转型
java·gitee·开源·开源软件
Vitalia28 分钟前
⭐算法OJ⭐寻找最短超串【动态规划 + 状态压缩】(C++ 实现)Find the Shortest Superstring
开发语言·c++·算法·动态规划·动态压缩
eternal__day33 分钟前
第三期:深入理解 Spring Web MVC [特殊字符](数据传参+ 特殊字符处理 + 编码问题解析)
java·前端·spring·java-ee·mvc
最后一个bug37 分钟前
PCI与PCIe接口的通信架构是主从模式吗?
linux·开发语言·arm开发·stm32·嵌入式硬件
落落鱼201338 分钟前
TP6图片操作 Image::open 调用->save()方法时候报错Type is not supported
开发语言
Niuguangshuo40 分钟前
Python 设计模式:外观模式
python·设计模式·外观模式
iccb101343 分钟前
在线聊天系统中的多窗口数据同步技术解密
java·github
慕离桑1 小时前
SQL语言的物联网
开发语言·后端·golang
"_rainbow_"1 小时前
Qt添加资源文件
开发语言·qt