Java 单一职责原则重构登录功能

一、单一职责原则核心定义
一个类只承担一类职责,只存在一个引起它修改的原因。
原始登录代码常把参数校验、数据库查询、密码加密、响应封装全部写在一个类中,耦合严重;重构后按职责拆分:校验、用户数据、登录业务、返回结果四类独立类。
二、未重构前(违反单一职责,臃肿代码)

点击查看代码
public class LoginService {
    public String login(String username, String password) {
        // 1.参数校验
        if(username == null || username.trim().length() == 0){
            return "用户名不能为空";
        }
        if(password == null || password.length() < 6){
            return "密码长度不能小于6位";
        }
        // 2.查询数据库用户
        User dbUser = getUserFromDB(username);
        if(dbUser == null){
            return "用户不存在";
        }
        // 3.密码加密对比
        String encryptPwd = encrypt(password);
        if(!dbUser.getPassword().equals(encryptPwd)){
            return "密码错误";
        }
        // 4.生成登录成功返回信息
        return "登录成功,欢迎:" + username;
    }
    private User getUserFromDB(String name){
        // 模拟数据库查询
        return new User(name, "123456");
    }
    private String encrypt(String pwd){
        return pwd + "_md5";
    }
}
class User{
    private String username;
    private String password;
    public User(String u, String p){
        this.username = u;
        this.password = p;
    }
    public String getPassword(){return password;}
}

问题:一个类承担参数校验、数据查询、加密、登录业务、结果封装5 个职责,任意一处规则变更都要修改此类,易引入 bug。

三、按单一职责拆分重构

  1. 职责 1:参数校验类(只负责登录参数合法性校验)
点击查看代码
public class LoginValidator {
    public String validate(String username, String password) {
        if(username == null || username.isBlank()){
            return "用户名不能为空";
        }
        if(password == null || password.length() < 6){
            return "密码长度不能小于6位";
        }
        return null;
    }
}
2. 职责 2:用户数据访问类(只负责数据库用户查询)
点击查看代码
public class UserDao {
    public User findUserByUsername(String username) {
        // 模拟DB查询逻辑
        return new User(username, "123456_md5");
    }
}
3. 职责 3:密码加密工具类(只做密码加密运算)
点击查看代码
public class PasswordEncryptUtil {
    public String encrypt(String rawPwd) {
        return rawPwd + "_md5";
    }
}
4. 职责 4:核心登录业务类(仅统筹登录流程,协调其他类)
点击查看代码
public class LoginService {
    private final LoginValidator validator = new LoginValidator();
    private final UserDao userDao = new UserDao();
    private final PasswordEncryptUtil encryptUtil = new PasswordEncryptUtil;

    public String login(String username, String password) {
        // 1.委托校验类做参数校验
        String validateMsg = validator.validate(username, password);
        if(validateMsg != null){
            return validateMsg;
        }
        // 2.委托Dao查询用户
        User user = userDao.findUserByUsername(username);
        if(user == null){
            return "用户不存在";
        }
        // 3.委托工具类加密对比密码
        String inputEncrypt = encryptUtil.encrypt(password);
        if(!user.getPassword().equals(inputEncrypt)){
            return "密码错误";
        }
        return "登录成功,欢迎:" + username;
    }
}
5. 用户实体(仅承载用户数据,纯 POJO)
点击查看代码
public class User {
    private String username;
    private String password;
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    public String getPassword() {
        return password;
    }
}
6. 测试调用
点击查看代码
public class TestLogin {
    public static void main(String[] args) {
        LoginService login = new LoginService();
        System.out.println(login.login("test", "123456"));
    }
}

四、重构后优势(贴合单一职责原则)
职责隔离
校验逻辑修改只改LoginValidator;数据库换数据源只改UserDao;加密算法切换只改工具类,互不干扰。
代码复用
加密、参数校验、用户查询可在其他业务模块直接复用,无需重复编写。
易维护、易测试
每个类功能单一,单元测试可独立针对校验、Dao、加密分别编写,定位 bug 速度更快。
符合开闭原则衍生收益
新增手机号登录、验证码校验时,仅新增校验实现,无需改动原有登录主流程。

posted @ 2026-06-18 15:39  pigeon1237  阅读(2)  评论(0)    收藏  举报