函数命名,应该使用哪个抽象层次

Function naming, which level of abstraction should be used

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

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 似乎在同一级别,而不是低于它。

希望我说清楚了。

我想就像大多数人所说的那样,由于不同的原因在以后增加重定向案例,最好选择 "shouldRedirectVisitorToHome(visitor)"

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

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

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

我一个都不说。

isPageVisitorACrawler(visitor) 使其特定于 "page visitor",但似乎与它没有直接关系。

shouldRedirectVisitorToHome(visitor) 表示特定用例。

在不知道如何确定 visitor 是否为爬虫的具体情况下(我假设 visitorUserAgentIP/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;
}

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

"Rich Domain Model"背后的想法是将属于领域实体的逻辑尽可能多地放入其中,并确保领域实体能够保持自身处于有效状态。

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