Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何重构过程代码?_C#_Design Patterns_Refactoring - Fatal编程技术网

C# 如何重构过程代码?

C# 如何重构过程代码?,c#,design-patterns,refactoring,C#,Design Patterns,Refactoring,我正在为网站创建密码重置功能。必须执行密码重置的第一步: 用户以密码重置形式输入其电子邮件 系统检查带有电子邮件的用户是否已注册 如果找到用户,系统将发送带有uniqe令牌的密码重置URL的电子邮件 若找不到用户,系统将发送电子邮件,通知已为此电子邮件启动密码重置,但用户帐户不存在 我有一个实现公共方法-RequestPasswordReset的服务类,该方法非常程序化: public void RequestPasswordReset(string email) { if(!IsVal

我正在为网站创建密码重置功能。必须执行密码重置的第一步:

  • 用户以密码重置形式输入其电子邮件
  • 系统检查带有电子邮件的用户是否已注册
  • 如果找到用户,系统将发送带有uniqe令牌的密码重置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方法添加实现,并且方法变得越来越复杂。 其他步骤可以是,例如,检查用户是否已经在另一个相关系统中注册,我可以建议他在我的系统中创建新帐户或为他创建用户帐户

    我正在研究命令模式——将服务类重构为单独的命令可能会更好,RequestPasswordReset可能就是其中的一个命令。但它并没有通过RequestPasswordReset方法中的步骤解决主要问题

    我还研究了责任链模式——按顺序处理步骤会很好,但我不知道如何使用它来处理控制流——应该实施的不同条件。另外,看起来每个处理程序都应该执行类似的操作,并且不清楚整个控制流是如何变化的

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

    这种方法违反了单一责任原则


    事实上,我不认为是这样。该服务的“单一责任”是重置用户的密码,通过与其他对象(用户存储库和邮件服务)协调,它可以很好地做到这一点。如果重置密码的过程发生变化,则该类将发生变化,这并没有错。

    使用此代码的最佳方法是确保对其进行彻底测试。确保所有代码路径都已测试

    然后,忘掉它

    不要认为所有代码都必须遵循设计模式、单一责任原则和其他类似的东西。这些模式是通过检查工作代码发现的


    这里有工作代码。克服它,开始下一个任务。

    我认为你的代码现在还不错。如果您确实想要重构某些东西,您可以将代码进一步拆分,以简化主方法的可读性;大概是这样的:

    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);
        }
    }
    

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

    +1罗伯特·C·马丁将责任定义为“改变的理由”。就我所见,虽然这个类做了一些相关的事情,但仍然只有一个原因需要更改。“经过彻底测试”的代码不一定设计良好或易于维护。我见过测试和代码本身一样难以理解的情况。在设计中稍微考虑一下会大大提高代码库的可维护性。多么糟糕的建议啊。“程序测试可以用来显示bug的存在,但决不能显示它们的缺失”~Edsger Dijkstra。测试本身并没有什么意义,好的设计总是受到欢迎的。我真的更喜欢找到干净、原始、易于阅读的代码,而不是一堆带有少量测试的意大利面条。测试可以帮助你重构,让你知道你没有破坏任何东西。重构对于代码来说是必不可少的。您提到的这些模式是为了帮助我们程序员编写其他人都能理解的高质量代码。每个人都能编写代码,很少有人能编写可读的代码。@gdy如果你阅读《设计模式》一书,你会发现这些模式已经存在。他们被写在那本书中作为交流的手段。现在每个人说“抽象工厂模式”的意思都是一样的。涵盖所有正式需求的测试将向您显示,在需求的实现中没有bug。任何其他错误都会出现在不需要的代码中,因此它要么是无关的代码,要么应该添加到需求中(并进行测试)。您对模式的处理方法似乎几乎是倒退的。检查模式以找到问题的解决方案。不要仅仅因为你的解决方案已经存在,就试图将它们与模式相适应(很糟糕?)。当代码的编写方式出现问题时,需要重构。正如一些答案所表明的,您的方法似乎没有任何问题。所讨论的示例非常简单,但我知道我必须在外部系统中添加用户搜索,如果找到,则创建新用户并发送电子邮件以重置新创建用户的密码。如果我需要更多的步骤来实现,该怎么办?需要时重构。以前没有。谢谢,我做过这样的事。这个例子是我真实代码的简化版本,所以我也做了其他重构操作。