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

如何使用Guice DI实现策略模式并注入不同策略实现类?

用Guice实现策略模式的两种方案

方案一:通过@Named注解区分策略实例

这种方式适合策略数量固定、不需要动态扩展的场景,直接在模块中绑定带命名标识的策略实现,然后在Client中注入对应实例。

1. 配置Guice模块

在自定义Module中,给两个策略实现绑定不同的@Named标识:

public class MetricModule extends AbstractModule {
    @Override
    protected void configure() {
        // 绑定A策略,标记为"A"
        bind(MetricCollectorStrategy.class)
            .annotatedWith(Names.named("A"))
            .to(AMetricCollector.class);
        // 绑定B策略,标记为"B"
        bind(MetricCollectorStrategy.class)
            .annotatedWith(Names.named("B"))
            .to(BMetricCollector.class);
        // 绑定MetricPublisher(如果它有依赖也会自动注入)
        bind(MetricPublisher.class);
    }
}

2. 在Client类中注入策略实例

通过构造方法注入带@Named标记的两个策略实例,然后根据条件选择调用:

public class Client {
    private final MetricCollectorStrategy aCollector;
    private final MetricCollectorStrategy bCollector;

    @Inject
    public Client(@Named("A") MetricCollectorStrategy aCollector,
                  @Named("B") MetricCollectorStrategy bCollector) {
        this.aCollector = aCollector;
        this.bCollector = bCollector;
    }

    public void processMetric(String condition) {
        MetricCollectorStrategy targetCollector = "useA".equals(condition) ? aCollector : bCollector;
        targetCollector.collectAndPublishMetric();
    }
}

方案二:用MapBinder管理所有策略

如果需要动态扩展策略(比如后续新增C、D策略),用MapBinder可以将所有策略统一管理在一个Map中,Client直接根据key获取对应策略,无需修改Client代码。

1. 配置Guice模块

使用MapBinder创建键值对形式的策略绑定:

public class MetricModule extends AbstractModule {
    @Override
    protected void configure() {
        // 创建String到MetricCollectorStrategy的MapBinder
        MapBinder<String, MetricCollectorStrategy> strategyMapBinder = MapBinder.newMapBinder(
                binder(), String.class, MetricCollectorStrategy.class);
        // 添加A策略,key为"A"
        strategyMapBinder.addBinding("A").to(AMetricCollector.class);
        // 添加B策略,key为"B"
        strategyMapBinder.addBinding("B").to(BMetricCollector.class);
        // 绑定MetricPublisher
        bind(MetricPublisher.class);
    }
}

2. 在Client类中注入策略Map

直接注入策略Map,根据条件对应的key获取策略实例:

public class Client {
    private final Map<String, MetricCollectorStrategy> strategyMap;

    @Inject
    public Client(Map<String, MetricCollectorStrategy> strategyMap) {
        this.strategyMap = strategyMap;
    }

    public void processMetric(String strategyKey) {
        MetricCollectorStrategy collector = strategyMap.get(strategyKey);
        if (collector == null) {
            throw new IllegalArgumentException("未找到对应策略:" + strategyKey);
        }
        collector.collectAndPublishMetric();
    }
}

额外优化:懒加载策略实例

如果策略实例初始化成本较高,可以注入Provider<MetricCollectorStrategy>延迟创建实例,只有在需要时才初始化:

// 以方案一为例,修改Client的注入方式
public class Client {
    private final Provider<MetricCollectorStrategy> aCollectorProvider;
    private final Provider<MetricCollectorStrategy> bCollectorProvider;

    @Inject
    public Client(@Named("A") Provider<MetricCollectorStrategy> aCollectorProvider,
                  @Named("B") Provider<MetricCollectorStrategy> bCollectorProvider) {
        this.aCollectorProvider = aCollectorProvider;
        this.bCollectorProvider = bCollectorProvider;
    }

    public void processMetric(String condition) {
        MetricCollectorStrategy collector = "useA".equals(condition) 
            ? aCollectorProvider.get() 
            : bCollectorProvider.get();
        collector.collectAndPublishMetric();
    }
}

内容的提问来源于stack exchange,提问作者Arpan Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:45:10