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

如何在SRP与DRY原则间平衡多数据源认证逻辑?

解决方案:抽象接口+依赖注入

你这种情况用抽象接口+依赖注入的方案最适合,能完美平衡DRY和SRP原则,具体实现思路如下:

1. 抽象数据源接口

先定义一个统一的数据源接口,把与数据源交互的逻辑封装起来,让认证逻辑与具体数据源解耦:

interface AuthDataSource {
    // 定义认证所需的数据源操作,比如根据登录DTO获取用户认证数据
    UserAuthData getAuthData(LoginDto dto);
}

2. 实现具体数据源类

为每个用户实体对应的数据源编写独立的实现类,每个类只负责自身数据源的连接与数据查询:

class DataSourceA implements AuthDataSource {
    UserAuthData getAuthData(LoginDto dto) {
        // 连接数据源A、查询认证数据的专属逻辑
    }
}

class DataSourceB implements AuthDataSource {
    UserAuthData getAuthData(LoginDto dto) {
        // 连接数据源B、查询认证数据的专属逻辑
    }
}

class DataSourceC implements AuthDataSource {
    UserAuthData getAuthData(LoginDto dto) {
        // 连接数据源C、查询认证数据的专属逻辑
    }
}

3. 创建通用认证基类

将核心的认证逻辑集中在这个基类中,通过构造函数注入AuthDataSource接口。基类只专注于通用认证流程,不关心具体使用哪个数据源:

class BaseAuth {
    private final AuthDataSource dataSource;

    // 构造注入数据源
    BaseAuth(AuthDataSource dataSource) {
        this.dataSource = dataSource;
    }

    void loginFunction(LoginDto dto) {
        // 通用认证逻辑:参数校验、调用数据源获取数据、密码校验、生成令牌等
        UserAuthData authData = dataSource.getAuthData(dto);
        // 后续统一的认证步骤...
    }
}

4. 绑定具体认证与数据源(可选)

如果需要为每个用户实体提供单独的认证类标识,只需继承BaseAuth并传入对应数据源即可,无需重复编写登录逻辑:

class AuthA extends BaseAuth {
    AuthA() {
        super(new DataSourceA());
    }
}

class AuthB extends BaseAuth {
    AuthB() {
        super(new DataSourceB());
    }
}

class AuthC extends BaseAuth {
    AuthC() {
        super(new DataSourceC());
    }
}

方案优势

  • 符合DRY原则:通用认证逻辑仅实现一次,所有认证场景复用该逻辑
  • 符合SRP原则:BaseAuth只负责认证流程,每个DataSource只负责对应数据源的操作,职责单一
  • 扩展性强:新增用户实体时,只需添加新的AuthDataSource实现类,无需修改原有认证逻辑

内容的提问来源于stack exchange,提问作者Thet Bhone Htut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:05:30