繁体   English   中英

方法链的最佳实践(“return this”)

[英]Best practice for method chaining (“return this”)

我有一个名为DatabaseRow的抽象 class ,在派生和构造之后,主要从Load(object id)方法加载。

我有很多代码可以创建 class 的新实例,从 ID 加载它,然后返回 class。 我想将此代码简化为一行代码(为了简洁起见,有很多类只有返回这些 Loaded 实例的属性列表)。

我可以想到两种方法,但对我来说似乎都不“正确”。

1.我可以return this; 在我的Load方法结束时使用return new Derived().Load(id);

2.我可以创建一个通用方法来返回一个加载的方法。

public static T LoadRow<T>(object id) where T : DatabaseRow, new()
{
    T row = new T();
    row.Load(id);
    return row;
}

我见过一些其他代码使用与数字1相同的方法,但我从未见过任何有经验的开发人员推荐它,我也没有遇到 .NET 框架中做同样事情的任何方法,所以也许这不是最佳实践?

有谁知道任何其他可能比这两个更好的解决方案?

解决方案:

在阅读了 SirViver 的回答和评论后,我意识到返回的所有属性无论如何都需要缓存。 解决方案明显不同,但类似于选项2 (我不希望有人提出这个答案,因为我没有解释这部分设计)

所有这些实例都将从数据库中另一列检索到的值加载(如果您愿意,可以使用数据库关系)。 我没有尝试从该值加载新实例,而是创建了一个从列名加载实例并将加载的值缓存在字典中的方法。 这很好用,因为这是DatabaseRow class 的主要功能之一。

    private Dictionary<string, DatabaseRow> linkedRows;

    protected T GetLinkedRow<T>(string key) where T : DatabaseRow, new()
    {
        if (linkedRows.ContainsKey(key)) return (T)linkedRows[key];
        else
        {
            T row = new T();
            row.Load(this[key]);
            linkedRows.Add(key, row);
            return row;
        }
    }

就个人而言,我认为链接对 object 实例有实际副作用的方法调用是不好的做法。 老实说,我认为这两个例子都是相当丑陋的“黑客”,其唯一目的是节省两行代码。 我不认为结果实际上更具可读性。

如果您希望立即加载记录,我可能宁愿提供一个构造函数变体,该变体获取您从中加载的 ID,并使 object 在构造时自动填充,但当我考虑到它时,我不会打扰老实说——在一行中塞进更多信息并不能增加可读性和可维护性的代码。

1 号在某些圈子中越来越受欢迎; 当有一个接口定义了大量这些方法并且可以组装长链时,它通常被称为流利编程 成功执行此操作的关键是永远不要定义有时返回this ,但有时返回null的方法。 如果this总是返回(除非有例外),这是非常好的风格。

就我个人而言,我不喜欢 2 号这样的解决方案,因为它可以说违反了“一个责任”原则。

选项 1 仅在可以有一行而不被加载的情况下才可接受。 这是由于允许您执行此操作的模式:

return new Derived();

我个人更喜欢 static 方法。 但我怀疑这只是个人喜好问题。

正如 ssg 所说,另一个选项(让我们称之为选项 3)是重载 Derived 中的构造函数,这也可以工作,但是有很多构造函数通常会令人困惑,因为调用代码中没有任何描述正在发生的事情.

选项1:

return new Derived().Load(10);

选项 2:

return Derived.Load(10);

选项 3:

return new Derived(10);

选项 1 看起来您正在创建一个多余的 object。 选项 2 很好,因为它做了它看起来正在做的事情。 选项 3 对它的作用感到困惑。

尽管我个人喜欢返回this的方法,因为它允许将它们链接起来,但我认为在 .NET 框架(直到 Linq)中,这被不赞成。 浮现在脑海的原因是:

方法要么返回结果,要么更改 object 的 state。 返回this两者都有一点:更改 object 的 state 然后返回“结果” - 除了结果是修改后的原始 object。 这不符合用户的期望。

关于什么:

public class Derived : DatabaseRow
{
    public Derived(object id):
    {
        Load(id);
    }
}

并像这样使用它:

return new Derived(id);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM