【问题标题】:Function naming, which level of abstraction should be used函数命名,应该使用哪个抽象级别
【发布时间】:2015-06-01 15:41:46
【问题描述】:

我们在应用中有这样的用例:

If page visitor is a crawler, then redirect him to home page.

这是我们开发的两种在代码中实现的方法:

if (isPageVisitorACrawler(visitor)) {
    return redirectToHome();
}
if (shouldRedirectVisitorToHome(visitor)) {
    return redirectToHome();
}

好的。所以我相信第一个版本信息量更大,但其他人说第二个版本在适应方面更好。这意味着如果我们必须在用户必须被重定向到家时添加另一个条件,那么使用第二个版本会更容易和更清晰。

if (isPageVisitorACrawler(visitor) || isPageVisitorBanned(visitor)) {
    return redirectToHome();
}
if (shouldRedirectVisitorToHome(visitor)) {
    return redirectToHome();
}

在这个级别上,秒仍然是一样的。

我的问题是,我们什么时候应该将这些函数包装成更大(更通用)的函数,或者是否应该这样做?

我记得 Bob 叔叔说过我们不应该在一个函数中混合抽象级别。我相信,函数应该只调用比其抽象级别低一级的函数,而shouldRedirectVisitorToHome 似乎在同一级别,而不是更低。

我希望我说清楚了。

【问题讨论】:

    标签: function naming-conventions naming software-design


    【解决方案1】:

    我不会说任何一个。

    isPageVisitorACrawler(visitor) 使其特定于“页面访问者”,但看起来与它没有直接关系。

    shouldRedirectVisitorToHome(visitor) 表示特定的用例。

    在不知道如何确定visitor 是否是爬虫的具体情况下(我假设visitor 有UserAgent 或IP/Host 属性),最合乎逻辑的假设是让它visitor.IsCrawler() 和 visitor.IsBanned() 并确定类似

    的操作
    public class Visitor 
    {
        private string userAgent;
        private UserStatus status = UserStatus.Active;
    
        public bool IsCrawler() 
        {
            return userAgent.Contains("Google Bot");
        }
    
        public bool IsBanned()
        {
            return status == UserStatus.Banned;
        }
    }
    
    // In your controller
    if(!security.HasAccessTo(visitor, page)) 
    {
        return RedirectToHome(); 
    }
    
    // example of basic implementation of HasAccessTo
    public bool HasAccessTo(Visitor visitor, Page page) 
    {
        if(visitor.IsCrawler() || visitor.IsBanned())
        {
            return false;
        }
    
        List<GroupPermission> permissions = permissionsRepository.GetPermissions(visitor);
        foreach(GroupPermission permission in page.Groups) 
        {
            if(permissions.Contains(permission))
            {
                return true;
            }
        }
    
        // if no permissions were found, refuse
        return false;
    }
    

    这还将使您的代码更易于阅读,并且更易于重用确定访问者是爬虫还是被禁止的逻辑。每个开发人员,甚至是不熟悉项目的新开发人员,都会立即理解代码以及它应该做什么。

    “富域模型”背后的理念是尽可能多地在其中放入属于域实体的逻辑,并确保域实体能够将自身保持在有效状态。

    所有其他无法放入富域模型的逻辑都进入服务或工厂类。这将使更改更容易,因为您将其应用于域实体并且只有一个瘦服务层而不是贫乏的域模型和随着问题域的增长而变得难以维护的单一服务层。

    【讨论】:

      【解决方案2】:

      我认为就像大多数人所说的那样,由于不同的原因,在以后增加重定向案例时,最好使用“shouldRedirectVisitorToHome(visitor)”

      一旦有超过 2 个子案例可以达到相同的结果,我总是会将函数调用包装成更通用的调用。

      编辑:如果我认为将来会有更多案例,即使只有一个子案例,我也会进行通用调用

      【讨论】:

        【解决方案3】:

        “isPageVisitorACrawler(visitor)”在含义上更接近用例描述。但是,如果您想赋予该功能更通用的感觉,则第二个更可取。取决于你的需要。但是,如果您打算在充满 if 和 else 条件的情况下实现 isPageVisitorACrawler 函数的底层实现,则不应使用此方法的通用实现。我猜这违反了 SOLID oop 原则的 OCP 部分。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-17
          • 1970-01-01
          • 1970-01-01
          • 2015-10-14
          • 1970-01-01
          • 2018-04-17
          相关资源
          最近更新 更多