设计模式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

总结

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

相关推荐
向前看-2 小时前
验证码机制
前端·后端
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹3 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭3 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫3 小时前
泛型(2)
java
超爱吃士力架3 小时前
邀请逻辑
java·linux·后端
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白664 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp4 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea