一起来学设计模式之装饰器模式

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 前言目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~本节给大家讲一下设计模式中的装饰器模式,并结合实际业务场景给大家讲解如何使用~本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~装饰器模式装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给一个对象添加额外的职责,而不需要修改原始类的代码。这种模式是作为替代继承方式的一种实现。

前言

目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本节给大家讲一下设计模式中的装饰器模式,并结合实际业务场景给大家讲解如何使用~

本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~

装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给一个对象添加额外的职责,而不需要修改原始类的代码。这种模式是作为替代继承方式的一种实现。

装饰器模式中,有一个基本的接口或抽象类,定义了被装饰对象和装饰器对象之间的公共方法。装饰器对象和被装饰对象都实现了该接口或抽象类,并且装饰器对象还有一个成员变量指向被装饰对象,从而形成了一个装饰器对象链。

下面是一个简单的示例,展示了如何使用装饰器模式来扩展基础功能:

// 定义一个基本的组件接口
interface Component {
    void operation();
}
// 定义一个具体的组件类
class ConcreteComponent implements Component {
    public void operation() {
        System.out.println("ConcreteComponent.operation()");
    }
}
// 定义一个装饰器基类,维护一个指向被装饰对象的引用
class Decorator implements Component {
    private Component component;
    public Decorator(Component component) {
        this.component = component;
    }
    public void operation() {
        component.operation();
    }
}
// 定义一个具体的装饰器类,实现了基础功能的扩展
class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }
    public void operation() {
        super.operation();
        System.out.println("ConcreteDecorator.operation()");
    }
}
// 使用示例
public class DecoratorDemo {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decorator = new ConcreteDecorator(component);
        decorator.operation();
    }
}

在上面的示例中,Component 接口定义了一个 operation() 方法,被装饰对象 ConcreteComponent 实现了该接口,具有基础功能。

装饰器基类Decorator实现了 Component 接口,维护了一个指向被装饰对象的引用,它的 operation() 方法将调用被装饰对象的 operation() 方法。

具体的装饰器类 ConcreteDecorator 继承了Decorator类,实现了对基础功能的扩展,它的 operation() 方法先调用父类的 operation() 方法,再实现扩展的功能。

在客户端代码中,先创建一个被装饰对象 ConcreteComponent,然后用ConcreteDecorator对象来装饰它,最后调用operation()方法。在执行 operation() 方法时,先调用被装饰对象的 operation() 方法,再执行装饰器类的扩展功能。

最佳实践

假设电商平台上有各种商品可以卖,有些商品需要提供定制化的服务,如礼品包装、定制化贺卡等等。这时候可以使用装饰器模式,对商品进行装饰以提供相应服务。

下面是一个简单的示例:

假设有一个基础商品类 Product,其中包含商品的基本信息,如名称、价格等。同时有一个装饰器类 ProductDecorator,它继承自 Product,并包含一个Product对象作为成员变量,用于装饰商品。具体的装饰器类可以继承 ProductDecorator 并重写其中的方法,实现相应的装饰效果。

// 基础商品类
public class Product {
    private String name;
    private double price;
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public double getPrice() {
        return price;
    }
}
// 装饰器基类
public class ProductDecorator extends Product {
    protected Product product;
    public ProductDecorator(Product product) {
        super(product.getName(), product.getPrice());
        this.product = product;
    }
    @Override
    public String getName() {
        return product.getName();
    }
    @Override
    public double getPrice() {
        return product.getPrice();
    }
}
// 礼品包装装饰器
public class GiftWrapDecorator extends ProductDecorator {
    private static final double GIFT_WRAP_PRICE = 5.0;
    public GiftWrapDecorator(Product product) {
        super(product);
    }
    @Override
    public String getName() {
        return super.getName() + " (gift wrap)";
    }
    @Override
    public double getPrice() {
        return super.getPrice() + GIFT_WRAP_PRICE;
    }
}
// 定制化贺卡装饰器
public class GreetingCardDecorator extends ProductDecorator {
    private static final double GREETING_CARD_PRICE = 3.0;
    private String message;
    public GreetingCardDecorator(Product product, String message) {
        super(product);
        this.message = message;
    }
    @Override
    public String getName() {
        return super.getName() + " (with greeting card)";
    }
    @Override
    public double getPrice() {
        return super.getPrice() + GREETING_CARD_PRICE;
    }
    public String getMessage() {
        return message;
    }
}

在上述代码中,ProductDecorator 作为装饰器的基类,继承自 Product。具体的装饰器类 GiftWrapDecoratorGreetingCardDecorator 都继承自 ProductDecorator,并实现其相应的方法,实现相应的装饰效果。其中 GreetingCardDecorator 还包含一个 message 成员变量,用于存储定制化贺卡的内容。这样,当需要对商品进行定制化的服务时,只需要对商品对象进行装饰即可。

结束语

设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲外观模式~

本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~

相关文章

项目源码(源码已更新 欢迎star⭐️)

Kafka 专题学习

项目源码(源码已更新 欢迎star⭐️)

ElasticSearch 专题学习

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

博客(阅读体验较佳)


















相关文章
|
8月前
|
设计模式 存储 缓存
聊聊Java设计模式-装饰器模式
装饰器模式允许向一个现有的对象添加新的功能,同时不改变其结果。比如Java 中的IO框架中,`FileInputStream`(处理文件)、`ByteArrayInputStream`(处理字节数组)、`BufferedInputStream`(带缓存的处理类)等就是对`InputStream`进行的功能扩展,这就是装饰器模式的典型应用。
67 1
聊聊Java设计模式-装饰器模式
|
8月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
76 2
|
8月前
|
设计模式
设计模式之装饰器模式
设计模式之装饰器模式
|
8月前
|
设计模式
设计模式-装饰器模式
设计模式-装饰器模式
|
3月前
|
设计模式 XML Java
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
41 0
|
21天前
|
设计模式 前端开发 JavaScript
前端必须掌握的设计模式——装饰器模式
装饰器模式是一种结构型设计模式,通过创建新类来包装原始对象,实现在不修改原有结构的前提下扩展新行为。其核心在于“组合”思想,使新功能可“即插即拔”。该模式具有解耦性、灵活性和动态性等特点,广泛应用于类的面向对象编程语言中,如JavaScript的注解和TypeScript的写法。示例中,通过装饰器模式为游戏角色动态添加装备,展示了其强大的扩展性和灵活性。
|
8月前
|
设计模式 Java
Java一分钟之-设计模式:装饰器模式与代理模式
【5月更文挑战第17天】本文探讨了装饰器模式和代理模式,两者都是在不改变原有对象基础上添加新功能。装饰器模式用于动态扩展对象功能,但过度使用可能导致类数量过多;代理模式用于控制对象访问,可能引入额外性能开销。文中通过 Java 代码示例展示了两种模式的实现。理解并恰当运用这些模式能提升代码的可扩展性和可维护性。
70 1
|
4月前
|
设计模式 Java
Java设计模式-装饰器模式(10)
Java设计模式-装饰器模式(10)
|
7月前
|
设计模式 Java
Java设计模式:深入装饰器模式的三种写法(六)
Java设计模式:深入装饰器模式的三种写法(六)
|
7月前
|
设计模式 架构师 安全
设计模式第五讲-装饰器模式和代理模式详解
远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
284 0