基于枚举选择依赖对象:优化PubSub消息发布的设计模式咨询
解决方案:策略模式 + Spring Bean自动装配
针对你遇到的扩展性问题,最适合的方案是策略模式结合Spring的自动装配特性,彻底消除if-else分支,新增协议时只需新增实现类,无需修改原有业务代码。
具体实现步骤:
1. 定义统一的Publisher接口
先抽象出所有PubSub发布器的通用行为,确保所有实现类遵循同一规范:
public interface MessagePublisher { void publish(String message); }
2. 实现现有Publisher并添加类型标记
给每个具体的Publisher实现类添加自定义注解,绑定对应的SubscriptionType枚举值:
首先定义自定义注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface BindSubscriptionType { SubscriptionType value(); }
然后改造现有实现类:
@Component @BindSubscriptionType(SubscriptionType.WEBSOCKET) public class WebSocketPublisher implements MessagePublisher { @Override public void publish(String message) { // WebSocket发布逻辑 } } @Component @BindSubscriptionType(SubscriptionType.GRPC) public class GrpcPublisher implements MessagePublisher { @Override public void publish(String message) { // GRPC发布逻辑 } }
3. 创建Publisher工厂类
利用Spring的上下文,自动收集所有MessagePublisher实现类,按SubscriptionType映射存储,提供获取对应发布器的方法:
@Component public class PublisherFactory { private final Map<SubscriptionType, MessagePublisher> publisherMap; // 构造函数注入所有MessagePublisher Bean,自动完成映射 public PublisherFactory(List<MessagePublisher> publishers) { this.publisherMap = publishers.stream() .collect(Collectors.toMap( publisher -> publisher.getClass().getAnnotation(BindSubscriptionType.class).value(), Function.identity() )); } public MessagePublisher getPublisher(SubscriptionType type) { MessagePublisher publisher = publisherMap.get(type); if (publisher == null) { throw new IllegalArgumentException("Unsupported SubscriptionType: " + type); } return publisher; } }
4. 改造业务服务类
注入PublisherFactory,直接通过枚举获取对应发布器,彻底去掉if-else:
@Service public class MessagePublishService { private final PublisherFactory publisherFactory; public MessagePublishService(PublisherFactory publisherFactory) { this.publisherFactory = publisherFactory; } public void publishMessage(SubscriptionType type, String message) { MessagePublisher publisher = publisherFactory.getPublisher(type); publisher.publish(message); } }
5. 新增协议的扩展方式
当需要新增协议(比如MQTT)时,只需两步:
- 给
SubscriptionType枚举添加新的枚举值MQTT - 新建一个实现
MessagePublisher的类,添加@BindSubscriptionType(SubscriptionType.MQTT)注解并实现publish逻辑:
@Component @BindSubscriptionType(SubscriptionType.MQTT) public class MqttPublisher implements MessagePublisher { @Override public void publish(String message) { // MQTT发布逻辑 } }
无需修改任何原有业务代码,Spring会自动将新的Publisher纳入工厂的映射中。
方案优势
- 开闭原则:新增协议时无需修改原有代码,仅需添加新的实现类
- 代码简洁:消除冗余的if-else分支,业务逻辑更清晰
- 可维护性:每个Publisher的职责单一,便于单独测试和修改
内容的提问来源于stack exchange,提问作者BrownTownCoder
相关产品推荐
相关产品推荐

