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

· 浏览次数 : 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

[转帖]iptables命令详解和举例(完整版)

1、防火墙概述 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种。无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,以达到让它对出入网络的IP、数据进行检测。 目前市面上比较

[转帖]网卡bonding模式 - bond0、1、4配置

网卡bonding简介 网卡绑定就是把多张物理网卡通过软件虚拟成一个虚拟的网卡,配置完毕后,所有的物理网卡的ip和mac将会变成相同的。多网卡同时工作可以提高网络速度,还可以实现网卡的负载均衡、冗余。 bonding模式 1 round-robin(mode=0) 轮转策略,轮流在每一个slave网

【转帖】网卡bonding模式 - bond0、1、4配置

网卡bonding简介 网卡绑定就是把多张物理网卡通过软件虚拟成一个虚拟的网卡,配置完毕后,所有的物理网卡的ip和mac将会变成相同的。多网卡同时工作可以提高网络速度,还可以实现网卡的负载均衡、冗余。 bonding模式 1 round-robin(mode=0) 轮转策略,轮流在每一个slave网

探索文件系统:高效、可靠的文件管理与访问机制

本篇文章探索了文件系统的功能规划,着重讨论了文件存储、索引节点和目录项的管理、缓存策略以及文件数据的存储等方面。文件系统作为计算机系统中重要的组成部分,对于实现高效、可靠的文件管理与访问机制至关重要。通过深入了解文件系统的基本单位、元信息记录和目录结构,我们可以更好地理解文件系统的工作原理,本文旨在为读者提供对文件系统功能规划的全面认识,以帮助他们更好地理解和应用文件系统相关的技术。

混沌演练实践(一)

混沌工程是通过主动制造故障场景并根据系统在各种压力下的行为表现确定优化策略的一种系统稳定性保障手段,简单说就是通过主动注入故障的方式、提前发现问题,然后解决问题规避风险。

618技术揭秘 - 大促弹窗搭投实践

618 大促来了,对于业务团队来说,最重要的事情莫过于各种大促营销。如会场、直播带货、频道内营销等等。而弹窗作为一个极其重要的强触达营销工具,通常用来渲染大促氛围、引流主会场、以及通过频道活动来提升频道复访等。因此,如果能将运营的策略及想法快速转化为弹窗的内容并触达给用户,这对于提升运营效率及玩法灵活性的是极其有意义的。

万字详解常用设计模式

本文是博主在工作中对常用设计模式的使用经验总结归纳而来分享给大家。 设计模式一共有23种,本文讲解涉及如下: 责任链模式 模板方法模式 发布订阅模式 策略模式 三大分类 业界一般将设计模式分为三大类: 创建型模式:对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。有五种创建型模

API 开发的后盾:平台工程提供强力动态支持

过去几年,开发团队一直在发展传统的 DevOps。一些开发人员认为,CloudOps 或 DeploymentOps 等新实践的兴起将会导致回到孤岛问题。其他人则不愿意在承担所有其他职责之外构建、部署、运行和维护运维。显然,确实需要新的云原生开发策略,而不是典型的 DevOps。这就是平台工程的用武

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

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