Spring Boot中Notifier接口不同实现的额外参数处理方案咨询
针对Notifier接口多实现参数解耦的优化方案
核心思路:解耦参数与实现类,同时保证类型安全与扩展性
你的核心问题是统一接口下不同实现的专属参数传递,既要避免紧耦合,又要兼顾可维护性。下面结合Spring Boot场景给出几种适配的实践方案,以及你提到的Builder/Decorator模式的正确用法:
方案1:强类型参数载体(推荐)
通过抽象基类+子类的方式,为每种通知类型定义专属的请求参数类,既保证类型安全,又能灵活扩展新的通知类型。
代码实现
- 定义抽象请求基类
public abstract class NotificationRequest { private String message; // 构造器、Getter/Setter public NotificationRequest(String message) { this.message = message; } public String getMessage() { return message; } }
- 实现各类型的专属请求类
// FCM专属请求 public class FCMNotificationRequest extends NotificationRequest { private String token; public FCMNotificationRequest(String message, String token) { super(message); this.token = token; } public String getToken() { return token; } } // SNS专属请求 public class SNSNotificationRequest extends NotificationRequest { private String topicArn; public SNSNotificationRequest(String message, String topicArn) { super(message); this.topicArn = topicArn; } public String getTopicArn() { return topicArn; } }
- 修改Notifier接口与实现类
public interface Notifier { void send(NotificationRequest request); // 兼容原有单参数send方法的默认实现 default void send(String message) { send(new NotificationRequest(message) {}); } } @Component("fcmNotifier") public class FCMNotifier implements Notifier { @Override public void send(NotificationRequest request) { if (!(request instanceof FCMNotificationRequest)) { throw new IllegalArgumentException("FCM通知需要传入FCMNotificationRequest参数"); } FCMNotificationRequest fcmReq = (FCMNotificationRequest) request; // 使用fcmReq.getMessage()和fcmReq.getToken()执行FCM发送逻辑 } } @Component("snsNotifier") public class SNSNotifier implements Notifier { @Override public void send(NotificationRequest request) { if (!(request instanceof SNSNotificationRequest)) { throw new IllegalArgumentException("SNS通知需要传入SNSNotificationRequest参数"); } SNSNotificationRequest snsReq = (SNSNotificationRequest) request; // 使用snsReq.getMessage()和snsReq.getTopicArn()执行SNS发送逻辑 } }
- Spring环境下的使用方式
通过@Qualifier指定注入的实现类,结合参数载体发送通知:
@Service public class NotificationService { @Autowired @Qualifier("fcmNotifier") private Notifier fcmNotifier; @Autowired @Qualifier("snsNotifier") private Notifier snsNotifier; public void sendFCM(String message, String token) { fcmNotifier.send(new FCMNotificationRequest(message, token)); } public void sendSNS(String message, String topicArn) { snsNotifier.send(new SNSNotificationRequest(message, topicArn)); } }
优点
- 类型安全,编译期即可发现参数错误
- 扩展性强,新增通知类型只需新增请求子类和Notifier实现
- 符合单一职责原则,参数与实现类职责清晰
方案2:Builder模式简化请求构建
你提到的Builder模式可以用来优化请求对象的创建流程,让代码更易读、更流畅,和强类型参数载体配合使用效果最佳。
代码实现
public class NotificationBuilder { private String message; private String fcmToken; private String snsTopicArn; public NotificationBuilder message(String message) { this.message = message; return this; } public NotificationBuilder fcmToken(String token) { this.fcmToken = token; return this; } public NotificationBuilder snsTopicArn(String topicArn) { this.snsTopicArn = topicArn; return this; } public FCMNotificationRequest buildFCM() { return new FCMNotificationRequest(message, fcmToken); } public SNSNotificationRequest buildSNS() { return new SNSNotificationRequest(message, snsTopicArn); } }
使用方式
public void sendFCMWithBuilder() { FCMNotificationRequest request = new NotificationBuilder() .message("您有新消息") .fcmToken("fcm-token-xxxx") .buildFCM(); fcmNotifier.send(request); }
方案3:Decorator模式处理横切逻辑
Decorator模式和参数传递是正交的,适合处理日志、重试、限流等横切关注点,完全可以和上面的方案结合使用,实现业务逻辑与通用逻辑的分离。
代码实现
// 日志装饰器 public class LoggingNotifierDecorator implements Notifier { private final Notifier delegate; public LoggingNotifierDecorator(Notifier delegate) { this.delegate = delegate; } @Override public void send(NotificationRequest request) { System.out.println("开始发送通知:" + request.getMessage()); try { delegate.send(request); System.out.println("通知发送成功"); } catch (Exception e) { System.err.println("通知发送失败:" + e.getMessage()); throw e; } } } // 重试装饰器 public class RetryNotifierDecorator implements Notifier { private final Notifier delegate; private final int retryTimes; public RetryNotifierDecorator(Notifier delegate, int retryTimes) { this.delegate = delegate; this.retryTimes = retryTimes; } @Override public void send(NotificationRequest request) { int attempt = 0; while (attempt < retryTimes) { try { delegate.send(request); return; } catch (Exception e) { attempt++; if (attempt >= retryTimes) { throw e; } // 重试间隔 try { Thread.sleep(1000 * attempt); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } } }
Spring环境下配置装饰器
通过@Bean包装原始Notifier:
@Configuration public class NotifierConfig { @Bean public Notifier fcmNotifierWithLoggingAndRetry(FCMNotifier fcmNotifier) { Notifier loggingDecorator = new LoggingNotifierDecorator(fcmNotifier); return new RetryNotifierDecorator(loggingDecorator, 3); } }
总结:最优组合方案
推荐采用强类型参数载体 + Builder模式 + Decorator模式的组合:
- 用强类型参数载体解决不同实现的专属参数传递问题,保证类型安全与扩展性
- 用Builder模式简化请求对象的创建,提升代码可读性
- 用Decorator模式处理日志、重试等横切逻辑,实现业务与通用逻辑的解耦
这种方案完全适配Spring Boot场景,新增通知类型或横切逻辑时只需新增对应类,无需修改原有代码,符合开闭原则。
内容的提问来源于stack exchange,提问作者KzeroJun
相关产品推荐
相关产品推荐

