代码优化心得

请问如何优化这段代码

public function resetPassword($email,$verifyCode,$newPassword)
{
    $user = User::findByEmail($email)->first();
    if ($user) {
        $codeData = EmailVerifyLog::findByEmail($email)->get()->last();
        if($codeData){
            if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
                $user->updatePassword($newPassword);
                $codeData->updateToExpired();
                return true;
            }
        }
    }
    return false;
}

上一篇看了大家的方案,蛮有启发的。总结了一下,主要有两种做法:
一、拆分职责,引入过滤器中间件
二、直接修改现有的代码

先说说拆分职责

我们回头看到,前两个产生if的地方都是在检查对象,再往下是验证code。对于一个具体的resetPassword()来说,检查对象相对会是一个比较“泛”的行为;而验证code则是resetPassword()的一个门槛。说白了,就是我压根还没开始真正的reset,就先有两种行为挡住了。所以我们可以尝试把这些行为作为resetPassword()的前置工作,那resetPassword()就改一下psw就行了

使用验证器:表单验证

'email' => 'exists:users,email'

使用中间件:

public function handle(Request $request, Closure $next)
{
    $email = $request->input('email');
    $verifyCode = $request->input('verifyCode');
    $codeData = EmailVerifyLog::findByEmail($email)->latest()->first();
    if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
        $codeData->updateToExpired();
        return $next($request);
    }
    throw new \Exception();
}

接着是直接修改现有的代码

1、使用文档提供的firstOr()、firstOrFail()可以直接让我们省去if:未找到时抛出异常
2、提前return,这个打破了我以往认为的代码行数越少越好的刻板思想,提前return的代码可读性比嵌套if高太多了

以下是我参考大家方案后采用的修改:

public function resetPassword($email,$verifyCode,$newPassword)
{
    if (!($user = $this->getUserInstanceByEmail($email))) {
        return false;
    }

    if(!($codeData = $this->getVerifyLogInstanceLatest($email))){
        return false;
    }

    if ($codeData->verifyCode($verifyCode) && $codeData->notExpired()) {
        $user->updatePassword($newPassword);
        $codeData->updateToExpired();
        return true;
    }

    return false;
}

这里将获取对象的行为进行封装,是受到最近看laravel源码的影响。
我发现源码中会尽可能将一些行为细化到单一的方法中,然后进行逻辑处理的方法只会调用这些单一的行为,而不用理会行为的具体实现。这样做会使得代码可读性、可扩展性大大提高。

附言 1  ·  3周前

首先谢谢留言

想说明的是,这是我自己试手的小功能,实际工作中我并不打算对现有的代码进行优化,功能下来了按照自己的习惯怎么快完成怎么好。这个优化是我在空闲时候想折腾的东西

另外我觉得进行优化是有助于我下次写代码时考量的东西的,我不一定在工作上用,但我很可能在自己的项目尝试

此外,经过尝试优化后,我开始能感受到其他作者代码模块的设计用意,我认为这挺有意思的

这帖子会比较倾向讨论优化的思路,谢谢大家

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 10

你和代码有一个能跑就行

3周前 评论
PHP-Coder 3周前

你和代码有一个能跑就行

3周前 评论
PHP-Coder 3周前

社会经验告诉我们,能跑的代码就不要去碰它。

3周前 评论
MyZy 2周前

不要为了优化而优化,很容易陷入设计的陷进。如果本身业务复杂性并不高,没必要为了所谓的优化去做过多的设计,从而导致代码量以及可读性变复杂,从而达到所谓的易扩展的效果,当然我也不是说代码不需要优化的道理。所有的技术都是为业务而服务,当你的代码无法支撑你现有业务的时候,也就是业务本身到了一定的复杂程度的时候就不得不去优化了。以最小的代价去发挥最大的业务价值,才是最优解。当然,设计模式是非常重要的,这一点是毋庸置疑的。

3周前 评论
Blsa 1周前
yWNN

往往没有那么多时间给你优化,上头一直催,只看结果。

3周前 评论
nff93

我一般是使用 firstOrFail 和 abort :dog:

public function resetPassword(string $email, string $verifyCode, string $newPassword)
{
    $user = User::findByEmail($email)->firstOrFail();

    $codeData = EmailVerifyLog::findByEmail($email)->latest()->firstOrFail();

    abort_if(
        $codeData->expired() || !$codeData->verifyCode($verifyCode), 400, 'xxx'
    );

    $user->updatePassword($newPassword);

    $codeData->updateToExpired();
}
3周前 评论
yzbfeng 2周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!