(工厂+策略)实现登录功能

· 浏览次数 : 2

小编点评

代码改造后的目的是改善代码可维护性,增加代码可扩展性,并减少代码重复性。 代码的改造说明如下: 1. 定义了一个接口`LoginStrategy`,用于定义登录逻辑的通用接口。 2. 创建了三种具体策略类,每个类实现了`LoginStrategy`接口的方法,分别对应不同的登录方式(账户登录、短信登录、微信登录)。 3. 创建了一个策略工厂,负责根据登录方式获取相应的策略对象。 4. 修改了`UserService`类,使用策略工厂获取登录策略,并将登录逻辑委托给策略对象进行处理。 5. 使用`@Autowired`注入`LoginStrategyFactory`,让`UserService`根据登录类型获取对应的策略对象。 6. 通过这种方式,`UserService`不再直接包含各种登录逻辑,而是通过策略工厂获取对应的策略对象来处理登录请求,降低代码重复性和提高代码可维护性。

正文

原始代码

业务层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的逻辑。

与(工厂+策略)实现登录功能相似的内容:

(工厂+策略)实现登录功能

原始代码 业务层UserService @Service public class UserService { public LoginResp login(LoginReq loginReq){ if(loginReq.getType().equals("account")){ System.ou

【交付高质量,用户高增长】-用户增长质量保证方法论

本文基于C端用户拉新的业务场景,以质量保证的全视角,总结了质量保证过程中的框架、策略、流程、规范、方法、工具以及实践,全面阐述了用户增长质量保证的价值观、方法论以及我们所理解的内涵,即高质量=质量策略多样化+质量流程标准化+质量活动规范化+质量工具平台化+质量运营常态化。

微盟电商-以造数工厂为底座的低成本自动化应用实现(一)

微盟电商-以造数工厂为底座的低成本自动化应用实现 SAAS服务的特点是能够以同一套代码基础,服务各种使用场景的客户,由此带来的业务组合与配置的多样性是造成测试在造数环节以及自动化测试的实施阶段面临繁琐与困难的根本原因。如何确保自动化的高效实施并降低投入成本?电商测试团队从业务角度出发落地了造数工厂+

设计模式学习(二)工厂模式——工厂方法模式+注册表

目录工厂方法模式的瑕疵注册表 工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式,示例的类图如下: 考虑一种情况:现在要在程序运行时,根据外部资源,动态的实例化对象。也就是说在编译期我们无法知道要实例化的对象的类型。因此在实例化的过程中,就需要加以判断。 例如,在我的例子中,要根据连接到主机的

[转帖]linux 性能分析工具 perf + FlameGraph

https://www.cnblogs.com/lausaa/p/12098716.html 常用命令: perf record -e cpu-clock -g -p $pid sleep 10 perf script -i perf.data > perf.unfold /FlameGraph-m

阿里400+天,我为什么离开阿里

阿里还是挺不错了,感谢公司,感谢同事们! 零丶前言 今天是我在阿里的lastday,明天我将回成都(此处嘴角弯,我爱成都),端午后入职另外一家互联网大厂。 在去年3月份的时候,我从成都的某家金融科技银行跳槽到杭州阿里巴巴淘天集团,这篇《跳槽!阿里工作100+天,菜鸡职业生涯的一点记录》记录了我跳槽动

AI来实现代码转换!Python转Java,Java转Go不在话下?

今天看到个有趣的网站,给大家分享一下。 该网站的功能很神奇,可以实现编程语言的转化。感觉在一些场景之下还是有点作用的,比如你原来跟我一样是做Java的,因为工作需要突然转Go。这个时候用你Java的经验 + 这个工具,或许可以起到一定的帮助作用。 工具的使用也很简单,只需要在左侧黏贴你想转换的原始代

Grafana 系列-统一展示-1-开篇

本文为系列文章-Grafana 统一展示,包括 Metrics、Tracing、Logging,并尽量实现在它们之间相互跳转。通过 Grafana LTM(Loki、Tempo、Mimir)可以实现比较完美的效果,但是即使没有 Grafana LTM, 通过其他 Grafana + 其他工具也能实现相对不错的结果。

[转帖]Linux 流量监控工具:iptraf-ng 的安装与使用

环境 Linux/Ubuntu 18.04 + 安装iptraf-ng-1.2.1,可编译安装,安装包链接:iptraf-ng-1.2.1.zip 解压iptraf-ng-1.2.1 unzip ./iptraf-ng-1.2.1.zip 安装ncurses(系统是ubuntu18.04) sudo

[转帖]datax安装+配置+使用文档

1 DataX离线同步工具DataX3.0介绍 DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、DRDS