Spring中如何避免链式if-else,按GrantFilter调用对应实现类方法?
Spring中处理GrantFilter多属性组合调用的最优实现方式
问题背景
我正在编写一个以GrantFilter作为输入的GraphQL Query API,需要根据Filter的不同属性组合调用不同对象的方法。API方法签名如下:
public GrantsConnection fetch(GrantFilter filter)
GrantFilter类的属性定义:
public class GrantFilter { private Boolean isPrimary; private String profileId; private String entityId; }
Filter的属性可组合为单个、两个或全部非空的情况,当前用链式if-else判断的方式维护成本高,且所有被调用对象都实现了同一接口,需要更优的实现方案。
最优实现:策略模式 + Spring自动装配
利用Spring的依赖注入能力结合策略模式,将每个Filter组合对应的处理逻辑封装为独立策略类,实现逻辑解耦和扩展性。
1. 定义策略接口
统一所有处理逻辑的契约,包含匹配判断和执行方法:
public interface GrantFetchStrategy { // 执行具体的查询逻辑 GrantsConnection fetch(GrantFilter filter); // 判断当前策略是否匹配传入的Filter boolean matches(GrantFilter filter); }
2. 实现具体策略类
针对每个Filter属性组合,创建对应的策略类并交给Spring管理:
// 处理仅isPrimary非空的情况 @Component public class PrimaryGrantFetchStrategy implements GrantFetchStrategy { @Override public GrantsConnection fetch(GrantFilter filter) { // 此处编写该组合对应的查询逻辑 } @Override public boolean matches(GrantFilter filter) { return filter.getIsPrimary() != null && filter.getProfileId() == null && filter.getEntityId() == null; } } // 处理仅profileId非空的情况 @Component public class ProfileGrantFetchStrategy implements GrantFetchStrategy { @Override public GrantsConnection fetch(GrantFilter filter) { // 此处编写该组合对应的查询逻辑 } @Override public boolean matches(GrantFilter filter) { return filter.getIsPrimary() == null && filter.getProfileId() != null && filter.getEntityId() == null; } } // 其他属性组合的策略类以此类推
3. 构建策略工厂
通过Spring自动注入所有策略实现类,提供匹配策略的查找能力:
@Component public class GrantFetchStrategyFactory { private final List<GrantFetchStrategy> strategies; // 构造函数注入所有GrantFetchStrategy类型的Bean public GrantFetchStrategyFactory(List<GrantFetchStrategy> strategies) { this.strategies = strategies; } // 根据Filter找到匹配的策略 public GrantFetchStrategy getMatchingStrategy(GrantFilter filter) { return strategies.stream() .filter(strategy -> strategy.matches(filter)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("无匹配的查询策略:" + filter)); } }
4. 在API中使用策略工厂
替换原有的if-else逻辑,通过工厂获取对应策略执行:
@Service public class GrantService { private final GrantFetchStrategyFactory strategyFactory; public GrantService(GrantFetchStrategyFactory strategyFactory) { this.strategyFactory = strategyFactory; } public GrantsConnection fetch(GrantFilter filter) { GrantFetchStrategy strategy = strategyFactory.getMatchingStrategy(filter); return strategy.fetch(filter); } }
方案优势
- 开闭原则:新增Filter属性组合时,只需新增对应的策略类,无需修改原有业务代码
- 代码解耦:每个策略类专注单一组合的处理逻辑,代码更清晰易维护
- Spring集成:利用Spring的自动装配能力,无需手动管理策略类的实例化和依赖
内容的提问来源于stack exchange,提问作者Sunil Kumar
相关产品推荐
相关产品推荐

