原始代码
业务层UserService
@Service public class UserService { public LoginResp login(LoginReq loginReq){ if(loginReq.getType().equals("account")){ System.out.println("用户名密码登录"); //执行用户密码登录逻辑 return new LoginResp(); }else if(loginReq.getType().equals("sms")){ System.out.println("手机号验证码登录"); //执行手机号验证码登录逻辑 return new LoginResp(); }else if (loginReq.getType().equals("we_chat")){ System.out.println("微信登录"); //执行用户微信登录逻辑 return new LoginResp(); } LoginResp loginResp = new LoginResp(); loginResp.setSuccess(false); System.out.println("登录失败"); return loginResp; } }
注意:我们重点讲的是设计模式,并不是登录的逻辑,所以以上代码并没有真正的实现登录功能
问题分析
- 业务层代码大量使用到了if...else,在后期阅读代码的时候会非常不友好,大量使用if...else性能也不高
- 如果业务发生变更,比如现在新增了QQ登录方式,这个时候需要修改业务层代码,违反了开闭原则
解决:
使用工厂方法设计模式+策略模式解决
改进代码
要将上述代码改为使用工厂模式和策略模式,首先我们需要定义几个关键元素:策略接口、具体策略类、策略工厂以及修改UserService来使用这些策略。下面是改造后的代码示例:
1. 定义策略接口
public interface LoginStrategy { LoginResp login(LoginReq loginReq); }
2. 创建具体策略类
AccountLoginStrategy
@Service public class AccountLoginStrategy implements LoginStrategy { @Override public LoginResp login(LoginReq loginReq) { System.out.println("用户名密码登录"); // 执行用户密码登录逻辑 return new LoginResp(); } }
SmsLoginStrategy
@Service public class SmsLoginStrategy implements LoginStrategy { @Override public LoginResp login(LoginReq loginReq) { System.out.println("手机号验证码登录"); // 执行手机号验证码登录逻辑 return new LoginResp(); } }
WeChatLoginStrategy
@Service public class WeChatLoginStrategy implements LoginStrategy { @Override public LoginResp login(LoginReq loginReq) { System.out.println("微信登录"); // 执行用户微信登录逻辑 return new LoginResp(); } }
3. 实现策略工厂
@Service public class LoginStrategyFactory { @Autowired private AccountLoginStrategy accountLoginStrategy; @Autowired private SmsLoginStrategy smsLoginStrategy; @Autowired private WeChatLoginStrategy weChatLoginStrategy; public LoginStrategy getLoginStrategy(String type) { switch (type) { case "account": return accountLoginStrategy; case "sms": return smsLoginStrategy; case "we_chat": return weChatLoginStrategy; default: throw new IllegalArgumentException("Invalid login type"); } } }
4. 修改UserService使用策略
@Service public class UserService { @Autowired private LoginStrategyFactory loginStrategyFactory; public LoginResp login(LoginReq loginReq){ LoginStrategy strategy = loginStrategyFactory.getLoginStrategy(loginReq.getType()); if(strategy == null){ LoginResp loginResp = new LoginResp(); loginResp.setSuccess(false); System.out.println("登录失败: 无效的登录类型"); return loginResp; } return strategy.login(loginReq); } }
通过这种方式,UserService不再直接包含各种登录逻辑,而是通过策略工厂获取对应的策略对象来处理登录请求,这使得代码更加灵活和可扩展。如果需要添加新的登录方式,只需增加一个新的策略类并修改工厂类即可,无需修改UserService的逻辑。