首页 文章

如何重构程序代码?

提问于
浏览
4

我正在为网站创建密码重置功能 . 必须实现密码重置的第一步:

  • 用户以密码重置形式输入他的电子邮件 .

  • 系统检查用户是否已注册电子邮件 .

  • 如果找到用户,系统会发送带有密码重置URL和唯一令牌的电子邮件 .

  • 如果未找到用户,系统将发送电子邮件通知已为此电子邮件启动密码重置,但用户帐户不存在 .

我有服务类,它实现了公共方法 - RequestPasswordReset,这个方法非常程序化:

public void RequestPasswordReset(string email)
{
    if(!IsValidEmail(email))
    {
        throw new ArgumentException("email");
    }

    var user = this.repository.FindByEmail(email);
    if(user != null)
    {
        user.PasswordResetToken.Set(this.tokenGenerator.NewToken());
        this.emailService.Send(this.from, 
                               user.Email, 
                               "Password reset", 
                               "Your reset url: http://mysite.com/?t=" + 
                                     user.PasswordResetToken.Value);
    }
    else
    {
    this.emailService.Send(this.from,
                        user.Email, 
                        "Requested password reset", 
                        "Someone requested password reset at http://mysite.com");
    }
}

此方法违反单一责任原则 - 它检查用户是否存在,重置用户令牌,发送电子邮件 .

这种解决方案的主要问题是,如果我需要添加额外的步骤,我必须为RequestPasswordReset方法和方法添加实现变得越来越复杂 . 例如,其他步骤可以是检查用户是否已经在另一个相关系统中注册,我可以建议他在我的系统中创建新帐户或为他创建用户帐户 .

我正在研究Command模式 - 将服务类重构为单独的命令可能会很好,而RequestPasswordReset可能是其中一个命令 . 但它没有解决RequestPasswordReset方法中的步骤的主要问题 .

我也在关注责任链模式 - 按顺序处理步骤会很好,但我不知道如何使用它来处理控制流程 - 应该实现的不同条件 . 此外,看起来每个处理程序应该执行类似的操作,并且不清楚整个控制流如何更改 .

重构这样的程序代码的最佳方法是什么?

3 回答

  • 6

    此方法违反了单一责任原则

    其实我觉得不行 . 该服务的“单一责任”是重置用户的密码,并通过与其他对象(用户存储库和邮件服务)协调来做到这一点 . 如果重置密码的过程发生变化,那么这个类将会改变,并且没有任何错误 .

  • 2

    我认为你的代码很好 . 如果你绝对想要重构一些东西,你可能会将代码分解一点,以简化main方法的可读性;像这样的东西:

    public void RequestPasswordReset(string email)
    {
        ValidateEmail(email); // May throw exception if invalid
    
        var user = this.repository.FindByEmail(email);
        if(user != null)
        {
            GenerateTokenAndSendPasswordResetEmail(user);
        }
        else
        {
            SendPasswordResetEmail(email);
        }
    }
    

    除此之外,我会保持原样 . 你的问题非常简单,所以没有理由寻找复杂的解决方案! :)

  • 2

    这段代码最好的办法是确保它经过全面测试 . 确保已测试所有代码路径 .

    然后,克服它!

    克服所有代码必须遵守设计模式,单一责任原则和其他此类内容的想法 . 通过检查工作代码发现了这些模式 .

    你在这里有工作代码 . 克服它并开始下一个任务 .

相关问题