【问题标题】:Making my class 'fluent'让我的课堂“流利”
【发布时间】:2015-04-17 08:53:29
【问题描述】:

我昨天发现,如果我像这样从每个方法返回类实例,我可以模拟一个流畅的接口......

public class IsThisFluent
{
    public IsThisFluent Stuff()
    {
        //...
        return this;
    }

    public IsThisFluent OtherStuff()
    {
        // ...
        return this;
    }
}

这就是它的全部吗?

我承认,我是一只头脑很少的熊,我想继续这样做,但我认为最好与成年人核实一下。

我错过了什么吗?

这种模式有没有我没有发现的“陷阱”?

【问题讨论】:

  • 这就是我一直这样做的方式......看看这个:codeproject.com/Articles/640997/…
  • 在使用不可变类时这样做是很常见的。 Jon Skeet 在某处使用这种模式编写俄罗斯方块控制台应用程序有一个很好的视频。编辑:这里是...vimeo.com/68331762
  • 这有点取决于你打算如何使用它,东西真的需要返回任何东西或事后对对象做任何事情吗?我不确定仅仅为了它而返回对象会对性能造成多大影响
  • 谢谢。这篇文章没有强调任何潜在的问题;那么,我可以假设没有。

标签: c# fluent


【解决方案1】:

差不多就是这样。

这是一篇非常好的文章: http://rrpblog.azurewebsites.net/?p=33

编辑
原来的网站好像已经死了,所以这里是WayBackMachine to the rescue

我也很喜欢这个答案中的这个例子: https://stackoverflow.com/a/1795027/131809

public class Coffee
 {
    private bool _cream;

    public Coffee Make { get new Coffee(); }
    public Coffee WithCream()
    {
      _cream = true;
      return this;
    }
    public Coffee WithOuncesToServe(int ounces)
    {
      _ounces = ounces;
      return this;
    }
 }

var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);

这提醒了我,我现在需要一杯咖啡。

【讨论】:

  • 谢谢。虽然我看到为什么存在“Set”属性(来自代码 pov),但我真的不明白 为什么 它存在。
【解决方案2】:

return this 不是 all 流畅的接口。 链接方法是构建流畅 API 的一种简单形式,但流畅 API 通常看起来像 DSL(特定领域的语言),而且设计起来要困难得多

以起订量为例:

new Mock<IInterface>()
    .Setup(x => x.Method())
    .CallBack<IInterface>(Console.WriteLine)
    .Returns(someValue);
  • Mock&lt;T&gt; 类型上定义的 Setup 方法返回 ISetup&lt;T, TResult&gt; 的实例。

  • ICallback&lt;TMock, TResult&gt; 定义的Callback 方法返回IReturnsThrows&lt;TMock,TResult&gt; 的实例。请注意,ISetup&lt;T, TResult&gt; 扩展了 IReturnsThrows&lt;TMock,TResult&gt;

  • 最后,ReturnsIReturns&lt;TMock,TResult&gt; 上定义并返回IReturnsResult&lt;TMock&gt;。另请注意,IReturnsThrows&lt;TMock,TResult&gt; 扩展了 IReturnsResult&lt;TMock&gt;

所有这些细微差别都会迫使您以特定顺序调用这些方法,并禁止您连续两次调用Setup。或者在打电话给Setup之前打电话给Returns

这些细节对于确保良好的用户体验非常重要。

要了解有关设计流畅界面的更多信息,请查看 Martin Fowler 在FluentInterface 上的文章。 FluentAssertions 是另一个很好的例子,说明了设计可能变得多么复杂,而且结果的可读性也更高。

【讨论】:

    【解决方案3】:

    不,差不多就是这样。

    背后的想法是,您可以将方法调用链接在一起,随时操纵内部状态。最终,Fluent interface 的主要目标是可读性,LINQ 就是一个很好的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 2013-04-01
      • 1970-01-01
      • 2010-12-31
      相关资源
      最近更新 更多