news 2026/4/16 8:21:29

优雅解耦!SpringBoot 工厂+策略模式统一多端登录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
优雅解耦!SpringBoot 工厂+策略模式统一多端登录

各位开发者好,我是在项目里被登录功能折磨过无数次的老码农。还记得三年前接手一个多端登录项目,用户名密码、微信、手机号验证码三种登录方式挤在一个if-else里,新增支付宝登录时整整改了 17 处代码,最后还漏了一处校验 —— 从此发誓再也不用 "面条代码" 处理登录逻辑。

今天就把结合工厂模式和策略模式的优雅实现分享出来,带你从需求分析到 Spring Boot 实战,彻底告别登录模块的维护噩梦。

一、需求分析:当产品说 "我们要支持 10 种登录方式"
1. 典型登录场景:代码里的 "联合国"

假设我们要实现一个支持三种登录方式的系统:

  • 用户名密码登录:需要校验密码加密、账号是否锁定

  • 微信扫码登录:需要调用微信开放平台 API,校验授权码

  • 手机号验证码登录:需要生成验证码、校验有效期和正确性

传统写法是写一个LoginService,用if-else判断登录类型:

public String login(String loginType, Map<String, Object> params) { if ("password".equals(loginType)) { // 用户名密码登录逻辑 } else if ("wechat".equals(loginType)) { // 微信登录逻辑 } else if ("sms".equals(loginType)) { // 手机号登录逻辑 } else { throw new IllegalArgumentException("不支持的登录类型"); } }

这种写法的问题在于:

  • 扩展性差:新增登录方式要改if-else,违反开闭原则

  • 职责混乱:所有逻辑挤在一个类里,可读性差

  • 复用困难:不同登录方式的公共逻辑(如用户校验)无法抽取

2. 设计模式选择:策略模式解耦算法,工厂模式创建实例

策略模式:将每种登录方式封装成独立策略类,实现统一接口,调用者无需关心具体实现 工厂模式:通过工厂类根据登录类型创建对应的策略实例,避免调用者直接 new 对象

二、Spring Boot 项目搭建:先搭好 "舞台"
1. 创建 Spring Boot 项目

添加 Web 依赖,项目结构如下:

src/main/java/com/example/login ├── config │ └── StrategyConfig.java // 策略Bean配置 ├── controller │ └── LoginController.java // 登录控制器 ├── factory │ └── LoginStrategyFactory.java // 登录策略工厂 ├── model │ └── LoginRequest.java // 登录请求参数 ├── service │ ├── impl │ │ ├── PasswordLoginStrategy.java // 用户名密码策略 │ │ ├── WechatLoginStrategy.java // 微信策略 │ │ └── SmsLoginStrategy.java // 手机号策略 │ └── LoginStrategy.java // 登录策略接口 └── Application.java
2. 定义统一登录策略接口
public interface LoginStrategy { // 登录类型标识,如"password"、"wechat" String getLoginType(); // 登录方法,参数用Map传递不同登录方式的参数 String execute(Map<String, Object> params); }
三、策略模式实现:每种登录方式都是 "独立演员"
1. 用户名密码登录策略
@Service publicclass PasswordLoginStrategy implements LoginStrategy { @Override public String getLoginType() { return"password"; } @Override public String execute(Map<String, Object> params) { String username = (String) params.get("username"); String password = (String) params.get("password"); // 模拟密码校验(实际应从数据库查询+密码解密) if (!"123456".equals(password)) { thrownew IllegalArgumentException("密码错误"); } // 模拟用户校验 checkUserLocked(username); return"登录成功(用户名密码)"; } private void checkUserLocked(String username) { // 调用用户服务检查账号是否锁定 System.out.println("检查用户" + username + "是否锁定"); } }
2. 微信扫码登录策略
@Service publicclass WechatLoginStrategy implements LoginStrategy { @Override public String getLoginType() { return"wechat"; } @Override public String execute(Map<String, Object> params) { String authCode = (String) params.get("authCode"); // 模拟调用微信接口获取用户信息 String openId = callWechatApi(authCode); // 模拟数据库查询用户绑定关系 String userId = getUserIdByOpenId(openId); if (userId == null) { thrownew IllegalArgumentException("微信账号未绑定系统用户"); } return"登录成功(微信扫码)"; } private String callWechatApi(String authCode) { // 实际应调用微信开放平台API System.out.println("调用微信接口,authCode=" + authCode); return"wechat_open_id_123"; } }
3. 手机号验证码登录策略
@Service publicclass SmsLoginStrategy implements LoginStrategy { @Override public String getLoginType() { return"sms"; } @Override public String execute(Map<String, Object> params) { String phone = (String) params.get("phone"); String code = (String) params.get("code"); // 模拟验证码校验(实际应从Redis获取) if (!"666888".equals(code)) { thrownew IllegalArgumentException("验证码错误"); } // 模拟用户校验 checkPhoneRegistered(phone); return"登录成功(手机号验证码)"; } private void checkPhoneRegistered(String phone) { // 检查手机号是否注册 System.out.println("检查手机号" + phone + "是否注册"); } }
四、工厂模式实现:让 "导演" 决定用哪个 "演员"
1. 登录策略工厂类
@Component publicclass LoginStrategyFactory { privatefinal Map<String, LoginStrategy> strategyMap; // 通过Spring依赖注入获取所有LoginStrategy实现类 public LoginStrategyFactory(Map<String, LoginStrategy> strategyMap) { this.strategyMap = strategyMap; } public LoginStrategy getStrategy(String loginType) { LoginStrategy strategy = strategyMap.get(loginType); if (strategy == null) { thrownew IllegalArgumentException("不支持的登录类型:" + loginType); } return strategy; } }

这里利用 Spring 的自动装配,将所有@Service标记的LoginStrategy实现类注入到strategyMap中,键为 Bean 名称(默认是类名首字母小写,如passwordLoginStrategy),但我们在策略类中通过getLoginType()返回自定义的类型标识,所以需要在配置类中调整 Bean 名称:

2. 策略 Bean 配置(关键!)
@Configuration publicclass StrategyConfig { @Bean("passwordStrategy") // 自定义Bean名称 public LoginStrategy passwordLoginStrategy() { returnnew PasswordLoginStrategy(); } @Bean("wechatStrategy") public LoginStrategy wechatLoginStrategy() { returnnew WechatLoginStrategy(); } @Bean("smsStrategy") public LoginStrategy smsLoginStrategy() { returnnew SmsLoginStrategy(); } }

然后在策略类中重写getLoginType()返回和前端约定的类型标识(如 "password"),并在工厂类中建立类型标识到 Bean 的映射:

// 修改工厂类的构造方法,建立正确映射 public LoginStrategyFactory(Map<String, LoginStrategy> strategyMap) { this.strategyMap = new HashMap<>(); strategyMap.forEach((beanName, strategy) -> this.strategyMap.put(strategy.getLoginType(), strategy) ); }
五、控制器集成:对外提供统一接口
1. 登录请求参数类
public class LoginRequest { private String loginType; // 登录类型,如"password"、"wechat" private Map<String, Object> params; // 具体参数,不同登录方式不同 // 省略getter/setter }
2. 登录控制器
@RestController @RequestMapping("/login") publicclass LoginController { privatefinal LoginStrategyFactory factory; @Autowired public LoginController(LoginStrategyFactory factory) { this.factory = factory; } @PostMapping public String login(@RequestBody LoginRequest request) { String loginType = request.getLoginType(); Map<String, Object> params = request.getParams(); LoginStrategy strategy = factory.getStrategy(loginType); return strategy.execute(params); } }
六、测试验证:三种登录方式轻松切换
1. 用户名密码登录请求
{ "loginType": "password", "params": { "username": "user123", "password": "123456" } }
2. 微信扫码登录请求
{ "loginType": "wechat", "params": { "authCode": "wechat_auth_code_456" } }
3. 新增登录方式:比如支付宝登录

只需新增AlipayLoginStrategy类并实现接口,无需修改现有代码:

@Service("alipayStrategy") public class AlipayLoginStrategy implements LoginStrategy { @Override public String getLoginType() { return "alipay"; } @Override public String execute(Map<String, Object> params) { // 支付宝登录逻辑 return "登录成功(支付宝)"; } }
七、核心优势:让代码具备 "抗需求变化体质"
1. 策略模式的好处
  • 解耦算法:每种登录逻辑独立在策略类中,可读性强

  • 易于扩展:新增登录方式只需添加新策略类,符合开闭原则

  • 方便测试:可以单独测试每个策略类,无需关心其他逻辑

2. 工厂模式的好处
  • 封装创建逻辑:调用者无需知道策略类的创建细节

  • 集中管理实例:通过 Spring 管理策略 Bean,支持依赖注入和生命周期管理

3. 结合 Spring Boot 的优势
  • 自动装配:通过@ServiceMap<String, LoginStrategy>自动收集所有策略 Bean

  • 类型安全:工厂类在运行时检查登录类型是否合法,避免NullPointerException

八、最佳实践:这些细节别忽略
1. 参数校验前置

在控制器中先对loginTypeparams做基础校验,比如必填参数检查,避免策略类中重复校验

2. 公共逻辑抽取

如果多种登录方式有公共逻辑(如登录成功后的 Token 生成),可以创建抽象策略类,让具体策略类继承

3. 日志和异常处理

在策略类中添加登录日志记录,统一捕获异常并返回友好的错误信息:

@Service public class PasswordLoginStrategy implements LoginStrategy { @Override public String execute(Map<String, Object> params) { try { // 登录逻辑 } catch (Exception e) { log.error("用户名密码登录失败:{}", e.getMessage()); throw new LoginException("登录失败,请重试"); // 自定义业务异常 } } }
4. 配置化登录类型

将支持的登录类型存储在配置文件中,前端调用时先获取支持的登录类型列表,避免硬编码

九、总结:设计模式让代码更有 "尊严"

回顾三年前的面条代码,再看现在的实现,最大的感受是:好的设计模式能让代码在需求变化面前保持优雅。工厂模式和策略模式的组合,就像给登录模块装了一个 "热插拔" 接口,新增功能时不用改核心逻辑,只需要添加新的 "插件"。

最后送大家一句口诀:登录逻辑别硬刚,策略模式来帮忙,工厂负责创实例,开闭原则记心上,Spring Boot 搭舞台,依赖注入真叫爽,需求万变不用慌,代码优雅没商量!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 11:35:47

基于Django的蔬菜批发管理系统

摘 要 随着现代农业和物流技术的飞速发展&#xff0c;蔬菜批发行业面临着巨大的市场机遇与挑战。传统的蔬菜批发管理方式已无法满足日益增长的市场需求和日益复杂的供应链环境。因此&#xff0c;开发一套高效、智能的蔬菜批发管理系统变得至关重要。本文旨在探讨蔬菜批发管理系…

作者头像 李华
网站建设 2026/4/15 18:32:59

从零上手Open-AutoGLM,快速构建你的自动化工作流

第一章&#xff1a;从零认识Open-AutoGLM浏览器插件Open-AutoGLM 是一款基于现代浏览器扩展架构开发的智能化辅助工具&#xff0c;专为提升用户在网页端与大语言模型交互效率而设计。该插件深度集成于主流浏览器环境中&#xff0c;能够自动识别页面内容并提供上下文感知的智能建…

作者头像 李华
网站建设 2026/4/16 10:38:56

AI Agent开发实战:LangGraph框架vs低代码平台,一篇搞定,建议收藏!

本文对比了LangGraph框架与可视化低代码平台(n8n、Dify)在AI Agent开发中的应用&#xff0c;分析了各自的优缺点。低代码平台适合快速构建PoC/MVP&#xff0c;但在高性能、复杂逻辑场景下存在局限。文章指出&#xff0c;低代码是探索起点而非生产终点&#xff0c;核心业务系统仍…

作者头像 李华
网站建设 2026/4/16 2:38:10

AutoGLM模型自动调优秘技,手把手教你提升大模型效率300%

第一章&#xff1a;AutoGLM模型自动调优秘技&#xff0c;手把手教你提升大模型效率300%在大模型应用日益普及的今天&#xff0c;如何高效优化模型推理性能成为关键挑战。AutoGLM作为专为GLM系列模型设计的自动调优框架&#xff0c;能够通过智能参数搜索与运行时编译技术&#x…

作者头像 李华
网站建设 2026/4/12 8:43:51

从安装失败到成功运行:我总结的7个Open-AutoGLM Windows部署核心要点

第一章&#xff1a;Windows本地部署Open-AutoGLM的挑战与总体思路在Windows环境下本地部署Open-AutoGLM面临多重技术挑战&#xff0c;包括依赖环境复杂、Python包兼容性问题以及GPU驱动支持不一致等。由于Open-AutoGLM基于PyTorch构建&#xff0c;并依赖CUDA加速&#xff0c;而…

作者头像 李华
网站建设 2026/4/16 10:40:49

智谱清言Open-AutoGLM实战指南(AutoGLM应用全攻略)

第一章&#xff1a;智谱清言Open-AutoGLM概述智谱清言Open-AutoGLM是基于AutoGLM技术构建的开放语言模型平台&#xff0c;旨在为开发者与研究者提供高效、灵活的大模型应用能力。该平台融合了生成式AI与自动化推理机制&#xff0c;支持自然语言理解、代码生成、多轮对话等多样化…

作者头像 李华