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

Java如何优化授权校验代码使其更符合面向对象设计规范?

面向对象改造方案(策略模式+工厂派发)

现有代码核心缺陷

  • isAuthValid方法耦合了所有授权类型的分支判断,随着授权类型增加会无限膨胀,维护成本极高
  • 违反开闭原则:新增授权类型必须修改原有方法的分支逻辑,极易引入存量功能bug
  • 并行流场景下使用普通toMap收集器存在并发风险
  • 不同类型的校验逻辑没有独立封装,无法针对单种授权类型做独立单元测试

改造步骤

1. 定义统一的授权校验策略接口

所有授权类型的校验逻辑都遵循这个接口规范,从根源上消除分支判断的必要:

public interface AuthValidityChecker {
    // 返回当前校验器支持的授权类型
    AuthType supportType();
    // 执行对应类型的授权有效性校验
    boolean check(AuthorizationValue authValue);
}

建议把原有代码中的常量AUTH_TYPE_A/AUTH_TYPE_B/AUTH_TYPE_C统一收敛为AuthType枚举值,避免魔法值问题。

2. 为每种授权类型实现独立的校验策略

把原来散落在isAuthTypeAValid/isAuthTypeBValid等方法里的逻辑,拆分到独立的实现类中,每个类只负责一种授权类型的校验:

// A类型授权校验器
public class TypeAAuthChecker implements AuthValidityChecker {
    // 按需注入校验需要的远程客户端、配置等依赖
    private final RemoteAuthClient remoteAuthClient;

    public TypeAAuthChecker(RemoteAuthClient remoteAuthClient) {
        this.remoteAuthClient = remoteAuthClient;
    }

    @Override
    public AuthType supportType() {
        return AuthType.AUTH_TYPE_A;
    }

    @Override
    public boolean check(AuthorizationValue authValue) {
        // 迁移原有isAuthTypeAValid的全部逻辑到这里
        return remoteAuthClient.validateTypeA(authValue);
    }
}

// B类型授权校验器
public class TypeBAuthChecker implements AuthValidityChecker {
    private final RemoteAuthClient remoteAuthClient;

    public TypeBAuthChecker(RemoteAuthClient remoteAuthClient) {
        this.remoteAuthClient = remoteAuthClient;
    }

    @Override
    public AuthType supportType() {
        return AuthType.AUTH_TYPE_B;
    }

    @Override
    public boolean check(AuthorizationValue authValue) {
        // 迁移原有isAuthTypeBValid的全部逻辑到这里
        return remoteAuthClient.validateTypeB(authValue);
    }
}

// C类型授权校验器
public class TypeCAuthChecker implements AuthValidityChecker {
    private final RemoteAuthClient remoteAuthClient;

    public TypeCAuthChecker(RemoteAuthClient remoteAuthClient) {
        this.remoteAuthClient = remoteAuthClient;
    }

    @Override
    public AuthType supportType() {
        return AuthType.AUTH_TYPE_C;
    }

    @Override
    public boolean check(AuthorizationValue authValue) {
        // 迁移原有isAuthTypeCValid的全部逻辑到这里
        return remoteAuthClient.validateTypeC(authValue);
    }
}

3. 实现校验策略工厂,完成自动派发

工厂类负责维护「授权类型-对应校验器」的映射,对外提供统一的校验入口,不需要任何if-else判断:

public class AuthCheckerFactory {
    private final Map<AuthType, AuthValidityChecker> checkerMap;

    // 如果你使用Spring等IOC容器,可直接注入所有AuthValidityChecker实现类,无需手动注册
    public AuthCheckerFactory(List<AuthValidityChecker> checkers) {
        this.checkerMap = checkers.stream()
                .collect(Collectors.toUnmodifiableMap(
                        AuthValidityChecker::supportType,
                        Function.identity()
                ));
    }

    // 无IOC场景的构造方法,手动注册所有校验器
    public AuthCheckerFactory(RemoteAuthClient remoteAuthClient) {
        this.checkerMap = Map.of(
                AuthType.AUTH_TYPE_A, new TypeAAuthChecker(remoteAuthClient),
                AuthType.AUTH_TYPE_B, new TypeBAuthChecker(remoteAuthClient),
                AuthType.AUTH_TYPE_C, new TypeCAuthChecker(remoteAuthClient)
        );
    }

    public boolean isValid(AuthorizationValue authValue) {
        AuthValidityChecker checker = checkerMap.get(authValue.getType());
        // 无匹配校验器时返回false,和原有逻辑保持一致
        return checker != null && checker.check(authValue);
    }
}

4. 简化原有流处理逻辑

替换原来的isAuthValid调用,同时修复并行流的收集器问题:

// 初始化工厂,可通过依赖注入获取实例
private final AuthCheckerFactory authCheckerFactory = new AuthCheckerFactory(remoteAuthClient);

private Map<UUID, Boolean> getAuthorizationValidityMap(UUID accountId) {
    return findCredentialsByAccountId(accountId)
            .parallelStream()
            .collect(Collectors.toConcurrentMap(
                    AuthorizationValue::getId,
                    authCheckerFactory::isValid
            ));
}

方案收益

  • 完全符合开闭原则:后续新增授权类型,只需要新增一个对应的AuthValidityChecker实现类,不需要修改任何原有校验、派发逻辑,无侵入风险
  • 职责单一:每个校验类只负责一种授权类型的校验逻辑,代码不会随业务迭代无限膨胀,单元测试可单独覆盖每个校验规则
  • 性能更优:类型到校验器的映射在工厂初始化时一次性构建,校验时的派发效率为O(1),比多层if-else串行判断性能更好
  • 依赖管理更清晰:每个校验器可以单独注入自己需要的依赖,不需要把所有依赖都堆在同一个校验类里

注意:如果你的授权值类型判断逻辑不是基于固定的类型字段,也可以把策略匹配逻辑改成boolean support(AuthorizationValue authValue),支持更灵活的匹配规则,核心派发逻辑不变。

内容的提问来源于stack exchange,提问作者Billy Keef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:48:14