Java设计模式之装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你在不改变对象结构的情况下,动态地将新功能附加到对象上。装饰器模式通过创建一个包装对象来实现这一目的,该包装对象包含了原始对象,并在其上添加了额外的行为。

在装饰器模式中,有四个主要的角色:

  1. 抽象组件(Component):定义了装饰器和具体组件的共同接口,可以是抽象类或接口。
  2. 具体组件(Concrete Component):实现了抽象组件的接口,是被装饰的原始对象。
  3. 抽象装饰器(Decorator):继承自抽象组件,持有一个抽象组件的引用,并在其上添加额外的行为。
  4. 具体装饰器(Concrete Decorator):继承自抽象装饰器,实现了额外的行为。

下面是一个简单的示例,展示了如何使用装饰器模式来扩展一个咖啡店的咖啡选择:

java 复制代码
// 抽象组件
interface Coffee {
    String getDescription();
    double getCost();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

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

// 抽象装饰器
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

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

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

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

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

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

    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 0.5;
    }
}

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

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

    @Override
    public double getCost() {
        return decoratedCoffee.getCost() + 0.2;
    }
}

// 使用示例
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 创建一个简单咖啡对象
        Coffee coffee = new SimpleCoffee();
        System.out.println("Description: " + coffee.getDescription());
        System.out.println("Cost: $" + coffee.getCost());

        // 使用装饰器来添加牛奶和糖
        Coffee decoratedCoffee = new MilkDecorator(new SugarDecorator(coffee));
        System.out.println("Description: " + decoratedCoffee.getDescription());
        System.out.println("Cost: $" + decoratedCoffee.getCost());
    }
}

在上面的示例中,抽象组件是Coffee接口,具体组件是SimpleCoffee类,抽象装饰器是CoffeeDecorator类,具体装饰器有MilkDecoratorSugarDecorator类。我们可以通过组合不同的装饰器来动态地扩展咖啡的描述和价格,而不需要修改原始的咖啡对象。

运行上述示例代码,输出如下:

复制代码
Description: Simple Coffee
Cost: $1.0
Description: Simple Coffee, Sugar, Milk
Cost: $1.7

可以看到,通过装饰器模式,我们成功地在不改变原始咖啡对象的情况下,动态地添加了牛奶和糖的描述和价格。这样的设计模式使得代码更加灵活、可扩展,并符合开闭原则。

相关推荐
方也_arkling7 小时前
【Java-Day08】static / final / 枚举
java·开发语言
橙淮7 小时前
Spring Bean作用域与生命周期全解析
java·spring
Chengbei117 小时前
一站式源码安全检测工具、云安全 / APP / 小程序源码敏感信息递归多层目录扫描AK、JWT、手机号、身份证等敏感信息
java·开发语言·安全·web安全·网络安全·系统安全·安全架构
llz_1127 小时前
web-第一次课后作业
java·开发语言·idea
秋98 小时前
Java项目运行5天左右自动宕机:系统性定位与解决方案
java·开发语言·python
小江的记录本8 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
DIY源码阁8 小时前
JavaSwing学生成绩管理系统 - MySQL版
java·数据库·mysql·eclipse
basketball6169 小时前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
JAVA面经实录91710 小时前
MyBatis面试题库
java·mybatis
小江的记录本10 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试