You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于枚举选择依赖对象:优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 00:06:18