装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言

现在我们有个如下的需求,设计一个邮件发奖的小系统,

需求

1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

1. 定义核心接口

java 复制代码
// 1. 定义核心接口
interface RewardHandler {
    void handleReward(Reward reward);
}

2. 基础实现类

java 复制代码
// 2. 基础实现类
class BasicRewardHandler implements RewardHandler {
    @Override
    public void handleReward(Reward reward) {
        // 实际发送邮件的核心逻辑
        sendEmail(reward);
    }

    private void sendEmail(Reward reward) {
        System.out.println("发送邮件奖励:" + reward.getAmount() + " 个 " + reward.getType());
    }
}

3. 装饰器抽象类

java 复制代码
// 3. 装饰器抽象类
abstract class RewardDecorator implements RewardHandler {
    private RewardHandler wrappee;

    public RewardDecorator(RewardHandler wrappee) {
        this.wrappee = wrappee;
    }

    @Override
    public void handleReward(Reward reward) {
        wrappee.handleReward(reward);
    }
}

4. 具体装饰器实现(可组合使用)

java 复制代码
// 4. 具体装饰器实现(可组合使用)
class ValidationDecorator extends RewardDecorator {
    public ValidationDecorator(RewardHandler wrappee) {
        super(wrappee);
    }

    @Override
    public void handleReward(Reward reward) {
        if (validate(reward)) {
            super.handleReward(reward);
        }
    }

    private boolean validate(Reward reward) {
        System.out.println("验证奖励有效性: " + reward.getId());
        return reward.getAmount() > 0;
    }
}

class LoggingDecorator extends RewardDecorator {
    public LoggingDecorator(RewardHandler wrappee) {
        super(wrappee);
    }

    @Override
    public void handleReward(Reward reward) {
        System.out.println("[LOG] 开始处理奖励 " + reward.getId());
        super.handleReward(reward);
        System.out.println("[LOG] 奖励处理完成 " + reward.getId());
    }
}

class EncryptionDecorator extends RewardDecorator {
    public EncryptionDecorator(RewardHandler wrappee) {
        super(wrappee);
    }

    @Override
    public void handleReward(Reward reward) {
        Reward encryptedReward = encrypt(reward);
        super.handleReward(encryptedReward);
    }

    private Reward encrypt(Reward reward) {
        System.out.println("加密奖励数据: " + reward.getId());
        return new Reward(reward.getId(), reward.getType(), reward.getAmount(), AES.encrypt(reward.getData()));
    }
}

5. 使用示例

java 复制代码
// 5. 使用示例
public class Main {
    public static void main(String[] args) {
        // 组合装饰器(验证 -> 日志 -> 加密 -> 核心处理)
        RewardHandler handler = new LoggingDecorator(
                new EncryptionDecorator(
                        new ValidationDecorator(
                                new BasicRewardHandler()
                        )
                )
        );

        Reward reward = new Reward("20230605-001", "金币", 100);
        handler.handleReward(reward);
    }
}

关键设计点说明:

  1. 灵活扩展性:通过装饰器链式组合(如验证→加密→日志),可动态调整处理流程
  2. 单一职责原则:每个装饰器只关注单一功能(验证、加密、日志等)
  3. 开闭原则:新增处理逻辑时无需修改已有代码
  4. 运行时组合:可根据不同环境配置装饰器组合(生产环境加验证,测试环境不加加密)

典型处理流程:

1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件

扩展建议:

  • 可添加RateLimitDecorator实现发放频率控制
  • 增加 FormatDecorator 处理奖励数据的格式化
  • 使用CircuitBreakerDecorator实现熔断机制
  • 通过配置中心动态调整装饰器组合顺序

这种模式特别适合需要动态组合多种预处理/后处理逻辑的场景,比继承方式更灵活,比责任链模式更易控制流程顺序。

相关推荐
Bs_MoneyMagnet14 分钟前
基于springboot+vue的滑雪场票务与装备租赁系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
野生技术架构师5 小时前
2026 Java 面试全套总结,八股 + 场景 + AI 相关面试考点
java·人工智能·面试
香吧香6 小时前
java服务异常日志只打印异常类型,没有堆栈定位分析
java·jvm·异常
qq_2518364577 小时前
AI 疾病自查功能SpringbootAI项目实战 · 技术实现文档
java·ai·ai编程
逆境不可逃7 小时前
Pi Agent 学习笔记:对话太长以后,如何压缩上下文
java
MetaLite7 小时前
JDK 8~26 核心特性一览:从 Stream 到 Scoped Values
java
wno7048 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
君顾18 小时前
上海24小时自助健身房系统开发实战指南:从架构设计到落地部署
java·开发语言·健身房
SL_staff9 小时前
别急着买商业规则引擎:90%风控场景根本不需要全量编码能力
java·程序员·groovy
ManageEngineITSM9 小时前
DevOps和ITIL是什么关系?是替代还是互补一文讲清
java·服务器·资产管理·变更管理