用提取方法重构,是否总是一个好主意?

杰夫

因此,我花了大约10到20分钟来重构〜30行方法。结果:74行。我认为那不好。当然,它可能更具可读性,但是您仍然必须跳到每种方法来找出细节。同样,提取所有这些方法也使我很难为它们找出好名字。如果将来我重构方法并想使用签名完全不同的现有方法名称怎么办?很难读-我至少是这么想的。

这是重构前的代码:

    public ActionResult Confirm(string id)
    {
        if (string.IsNullOrEmpty(id))
        {
            if (! IsLoggedIn())
            {
                return RedirectToAction("Login");
            }

            if(User.User.Confirmed)
            {
                return RedirectToAction("Index");
            }
            return View("PendingConfirmation");
        }

        int parsedId;
        if (!int.TryParse(id, out parsedId))
        {
            return Http(400, View("BadRequest", model: "EC2007: Could not parse int"));
        }

        return Try(() =>
        {
            UserBusinessLogic.ConfirmUser(parsedId);
            _authentication.SetAuthCookie(parsedId.ToString(CultureInfo.InvariantCulture), true);
            return RedirectToAction("Index");
        }, (code, errorCode) => Http(code, GenericErrorView(null, null, errorCode)));
    }

现在,这是重构版本:

    /// <summary>
    ///     Confirms the specified id.
    /// </summary>
    /// <param name="id">The id.</param>
    /// <returns></returns>
    public ActionResult Confirm(string id)
    {
        int parsedId;
        ActionResult actionResult;
        if (! AssertConfirmConditions(id, out parsedId, out actionResult))
        {
            return actionResult;
        }
        return Try(() => InternalConfirmUser(parsedId), (code, errorCode) => Http(code, GenericErrorView(null, null, errorCode)));
    }

    private ActionResult InternalConfirmUser(int parsedId)
    {
        UserBusinessLogic.ConfirmUser(parsedId);
        _authentication.SetAuthCookie(parsedId.ToString(CultureInfo.InvariantCulture), true);
        return RedirectToAction("Index");
    }

    private bool AssertConfirmConditions(string id, out int parsedId, out ActionResult actionResult)
    {
        actionResult = null;
        parsedId = 0;
        return 
            ! ShouldRedirectAwayFromConfirm(id, ref actionResult) 
            && CanParseId(id, ref parsedId, ref actionResult);
    }

    private bool CanParseId(string id, ref int parsedId, ref ActionResult actionResult)
    {
        if (int.TryParse(id, out parsedId))
        {
            return true;
        }
        actionResult = Http(400, View("BadRequest", model: "EC2007: Could not parse int"));
        return false;
    }

    private bool ShouldRedirectAwayFromConfirm(string id, ref ActionResult actionResult)
    {
        if (string.IsNullOrEmpty(id))
        {
            if (ShouldRedirectToLoginView(out actionResult)) return true;
            if (ShouldRedirectToIndex(ref actionResult)) return true;
            actionResult = View("PendingConfirmation");
            return true;
        }
        return false;
    }

    private bool ShouldRedirectToIndex(ref ActionResult actionResult)
    {
        if (User.User.Confirmed)
        {
            actionResult = RedirectToAction("Index");
            return true;
        }
        return false;
    }

    private bool ShouldRedirectToLoginView(out ActionResult actionResult)
    {
        actionResult = null;
        if (! IsLoggedIn())
        {
            actionResult = RedirectToAction("Login");
            return true;
        }
        return false;
    }

老实说,我更喜欢第一个版本。我在这里想念什么吗?当用几个控制流语句重构方法时,它变得很丑陋。

我应该坚持使用非重构版本吗?可以做得更好吗?

编辑:根据评论,我想指出,我使用了ReSharper的提取方法,我没有手动执行此操作。

丹尼尔·希尔加斯

我认为通过重构,您会使情况变得更糟,甚至更糟。

我的第一个想法如下所示:

public ActionResult Confirm(string id)
{
    if (string.IsNullOrEmpty(id))
    {
        return HandleMissingId();
    }

    int parsedId;
    if (!int.TryParse(id, out parsedId))
    {
        return Http(400, View("BadRequest", model: "EC2007: Could not parse int"));
    }

    return Try(() =>
    {
        ConfirmUser(parseId);
        return RedirectToAction("Index");
    }, ShowGenericError);
}

private void ConfirmUser(int userId)
{
    UserBusinessLogic.ConfirmUser(userId);
    _authentication.SetAuthCookie(userId.ToString(CultureInfo.InvariantCulture), true);
}

private ShowGenericError(int code, int errorCode)
{
    return Http(code, GenericErrorView(null, null, errorCode));
}

private ActionResult HandleMissingId()
{
    if (! IsLoggedIn())
    {
        return RedirectToAction("Login");
    }

    if(User.User.Confirmed)
    {
        return RedirectToAction("Index");
    }
    return View("PendingConfirmation");
}

此方法提取的方法封装了其他方法可能非常需要的特定概念/功能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

用提取方法重构,这总是一个好主意吗?

来自分类Dev

关闭ApplicationContext是否总是一个好主意?

来自分类Dev

提取大量String文字是一个好主意吗?

来自分类Dev

始终用final标记非虚拟方法是一个好主意吗?

来自分类Dev

在微控制器上用C ++调整动态数组的大小是否是一个好主意

来自分类Dev

在微控制器上用C ++调整动态数组的大小是否是一个好主意

来自分类Dev

contextlib.redirect_stdout总是一个好主意吗?

来自分类Dev

contextlib.redirect_stdout总是一个好主意吗?

来自分类Dev

用薄的Cache层覆盖jQuery的$ .ajax是一个好主意吗?

来自分类Dev

用接口创建模块只是一个好主意吗?

来自分类Dev

使用初始化部分进行模块注册是否是一个好主意?

来自分类Dev

在MongoDB中使用oplog进行版本控制是否是一个好主意

来自分类Dev

使用初始化部分进行模块注册是否是一个好主意?

来自分类Dev

在MongoDB中使用oplog进行版本控制是否是一个好主意

来自分类Dev

在执行awk操作之前过滤输入是否是一个好主意?

来自分类Dev

使用事务来确保elasticsearch和postgres数据同步是否是一个好主意?

来自分类Dev

通过引用传递Error对象,而不是从方法中抛出异常,是一个好主意吗?

来自分类Dev

组合实例VBO是一个好主意吗?

来自分类Dev

从cv :: Mat继承,一个好主意?

来自分类Dev

在Haskell中嵌套对是一个好主意

来自分类Dev

一个好主意是为此使用复合模式吗?

来自分类Dev

(何时)使用FluentAssertions是一个好主意?

来自分类Dev

使用NTFS压缩是一个好主意吗?

来自分类Dev

绑定PasswordBox密码不是一个好主意吗?

来自分类Dev

在Haskell中嵌套对是一个好主意

来自分类Dev

组合实例VBO是一个好主意吗?

来自分类Dev

别名cd推送-这是一个好主意吗?

来自分类Dev

总而言之,strlen不是一个好主意

来自分类Dev

检查每个细节上的SharedPreferences是一个好主意

Related 相关文章

  1. 1

    用提取方法重构,这总是一个好主意吗?

  2. 2

    关闭ApplicationContext是否总是一个好主意?

  3. 3

    提取大量String文字是一个好主意吗?

  4. 4

    始终用final标记非虚拟方法是一个好主意吗?

  5. 5

    在微控制器上用C ++调整动态数组的大小是否是一个好主意

  6. 6

    在微控制器上用C ++调整动态数组的大小是否是一个好主意

  7. 7

    contextlib.redirect_stdout总是一个好主意吗?

  8. 8

    contextlib.redirect_stdout总是一个好主意吗?

  9. 9

    用薄的Cache层覆盖jQuery的$ .ajax是一个好主意吗?

  10. 10

    用接口创建模块只是一个好主意吗?

  11. 11

    使用初始化部分进行模块注册是否是一个好主意?

  12. 12

    在MongoDB中使用oplog进行版本控制是否是一个好主意

  13. 13

    使用初始化部分进行模块注册是否是一个好主意?

  14. 14

    在MongoDB中使用oplog进行版本控制是否是一个好主意

  15. 15

    在执行awk操作之前过滤输入是否是一个好主意?

  16. 16

    使用事务来确保elasticsearch和postgres数据同步是否是一个好主意?

  17. 17

    通过引用传递Error对象,而不是从方法中抛出异常,是一个好主意吗?

  18. 18

    组合实例VBO是一个好主意吗?

  19. 19

    从cv :: Mat继承,一个好主意?

  20. 20

    在Haskell中嵌套对是一个好主意

  21. 21

    一个好主意是为此使用复合模式吗?

  22. 22

    (何时)使用FluentAssertions是一个好主意?

  23. 23

    使用NTFS压缩是一个好主意吗?

  24. 24

    绑定PasswordBox密码不是一个好主意吗?

  25. 25

    在Haskell中嵌套对是一个好主意

  26. 26

    组合实例VBO是一个好主意吗?

  27. 27

    别名cd推送-这是一个好主意吗?

  28. 28

    总而言之,strlen不是一个好主意

  29. 29

    检查每个细节上的SharedPreferences是一个好主意

热门标签

归档