设计模式Java实现-装饰者模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容:装饰者模式✈️

🍱本篇收录完整代码地址:gitee.com/diqirenge/d...🍱

楔子

小七以前学习设计模式的时候,总是看到一些奇奇怪怪的例子,比如什么披萨呀,面包呀啥的,就算当时看懂了,隔几天也就忘了。因为例子脱离业务,难以理解,也就更难以用在实际工作中,最后学了白学。

需求背景

假设我们有一个在线购物网站,其中有一个Product类表示商品。现在我们需要给商品添加一些额外的功能,比如给商品添加礼品包装、购买保险等。要求在不必改变原类和使用继承的情况下,动态地扩展这些功能。

分析设计

为了在不修改原有类的情况下,也可以动态地给商品添加各种附加功能,我们可以考虑使用继承的方式来进行拓展。但是考虑到直接继承,会因功能的不断扩展,而导致⼦类膨胀的问题,我们可以再抽象出一层(这里叫做抽象类装饰器),让具体的子类去实现抽象类装饰器,而不直接继承原有类。

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

模块名称

decorator

模块地址

gitee.com/diqirenge/d...

模块描述

装饰者模式代码示例

代码实现

1、定义组件接口

java 复制代码
/**
 * 定义组件接口
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public interface Product {
    /**
     * 添加到购物车
     */
    void addToCart();
}

2、定义抽象类装饰器

java 复制代码
/**
 * 抽象类装饰器
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public abstract class ProductDecorator implements Product {
    /**
     * 抽象接口
     */
    protected Product product;

    public ProductDecorator(Product product) {
        this.product = product;
    }

    @Override
    public void addToCart() {
        product.addToCart();
    }
}

3、编写具体的构建角色

java 复制代码
/**
 * 具体的构建角色 - 需要被装饰(拓展)的类
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public class ConcreteProduct implements Product {
    @Override
    public void addToCart() {
        System.out.println("将商品添加到购物车");
    }
}

4、创建具体的装饰者类,用于给商品添加附加功能

①具体装饰子类 - 为商品购买保险

java 复制代码
/**
 * 具体装饰子类 - 为商品购买保险
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public class InsuranceDecorator extends ProductDecorator {
    public InsuranceDecorator(Product product) {
        super(product);
    }

    @Override
    public void addToCart() {
        // 子类自己的拓展的逻辑
        System.out.println("为商品购买保险");
        // 调用父类的方法
        super.addToCart();
    }
}

②具体装饰子类 - 为商品添加礼品包装

java 复制代码
/**
 * 具体装饰子类 - 为商品添加礼品包装
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public class GiftWrappingDecorator extends ProductDecorator {
    public GiftWrappingDecorator(Product product) {
        super(product);
    }

    @Override
    public void addToCart() {
        // 子类自己的拓展的逻辑
        System.out.println("为商品添加礼品包装");
        // 调用父类的方法
        super.addToCart();
    }
}

5、编写测试类

java 复制代码
/**
 * 测试装饰者模式
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/12/06
 */
public class DecoratorTest {
    @Test
    public void testDecorator() {
        // 原始商品对象
        Product product = new ConcreteProduct();
        // 添加礼品包装的商品对象
        Product giftWrappedProduct = new GiftWrappingDecorator(product);
        // 添加保险的商品对象
        Product insuredProduct = new InsuranceDecorator(giftWrappedProduct);
        // 输出:为商品购买保险 -> 为商品添加礼品包装 -> 将商品添加到购物车
        insuredProduct.addToCart();
    }
}

6、测试结果

为商品购买保险

为商品添加礼品包装

将商品添加到购物车

实现要点

  1. 抽象构件⻆⾊(Component) - 定义抽象接⼝

    例子中为:Product

  2. 具体构件⻆⾊(ConcreteComponent) - 实现抽象接⼝

    例子中为:ConcreteProduct

  3. 装饰⻆⾊(Decorator) - 定义抽象类并继承接⼝中的⽅法,保证⼀致性

    例子中为:ProductDecorator

  4. 具体装饰⻆⾊(ConcreteDecorator) - 扩展装饰具体的实现逻辑

    例子中为:InsuranceDecorator和GiftWrappingDecorator

总结

装饰者模式是一种结构型设计模式,它允许你在不修改原始类代码的情况下,动态地给对象添加新的功能。

相关推荐
方圆想当图灵5 分钟前
缓存之美:万文详解 Caffeine 实现原理(下)
java·redis·缓存
栗豆包20 分钟前
w175基于springboot的图书管理系统的设计与实现
java·spring boot·后端·spring·tomcat
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
萧若岚1 小时前
Elixir语言的Web开发
开发语言·后端·golang
Channing Lewis1 小时前
flask实现重启后需要重新输入用户名而避免浏览器使用之前已经记录的用户名
后端·python·flask
Channing Lewis1 小时前
如何在 Flask 中实现用户认证?
后端·python·flask
酱学编程2 小时前
java中的单元测试的使用以及原理
java·单元测试·log4j
我的运维人生2 小时前
Java并发编程深度解析:从理论到实践
java·开发语言·python·运维开发·技术共享
一只爱吃“兔子”的“胡萝卜”2 小时前
2.Spring-AOP
java·后端·spring
HappyAcmen2 小时前
Java中List集合的面试试题及答案解析
java·面试·list