【问题标题】:Why use a Fluent Interface?为什么要使用流畅的界面?
【发布时间】:2009-12-30 10:39:50
【问题描述】:

与经典属性相比,使用它的最大收获是什么?

我知道实例名称的重复消失了,但仅此而已?

public class PropClass
{
  public Object1 object1 { get; set; }
  public Object2 object2 { get; set; }
}

PropClass propClass = new PropClass();
propClass.object1 = o1;
propClass.object2 = o2;

public class FluentClass
{
    public Object1 object1 { get; private set; }
    public Object2 object2 { get; private set; }

    public FluentClass SetObject1(Object1 o1)
    {
        object1 = o1;
        return this;
    }

    public FluentClass SetObject2(Object1 o2)
    {
        object1 = o2;
        return this;
    }
}

FluentClass fluentClass = new FluentClass().SetObject1(o1).SetObject1(o2);

【问题讨论】:

标签: c# fluent-interface


【解决方案1】:

恕我直言,使用流畅的界面设置属性并没有太大的收获,尤其是使用 C# 3.0 类初始化程序。当您开始链接方法和操作时,流畅的接口会变得更加有趣。

【讨论】:

  • 可能不是用于设置属性,而是用于链接操作,例如乘以 5、加 3、除以 7 等...
  • Fluent Interfaces 在处理Specification Pattern 时很有用。它将 n 个规范链接为一个,如 How to combine conditions dynamically? 中给出的
【解决方案2】:

这取决于它的使用方式。在您的示例中,使用流畅的界面没有多大意义。

另一方面,流畅的界面非常适合构建器之类的东西,尤其是当您将多个流畅的构建器链接在一起时(例如汽车制造商/引擎制造商)。我已经非常广泛地使用了Test Data Builders,它们工作得非常好。你可以在没有流畅界面的情况下做同样的事情,但使用起来不太好。

此外,还有 Martin Fowler explains here 的领域特定语言角度。

唯一的问题是人们有时会疯狂使用流畅的接口并创建过于冗长的 API,但在我看来,这与其说是流畅的接口问题,不如说是应用程序/实现问题。

【讨论】:

    【解决方案3】:

    当您想要减少代码重复并减少每个类之间的依赖关系时,Fluent 模式(Builder)将是最大的好处。对于 C# 3.5+,您可以通过创建方法扩展(如 LINQ 或以下代码)来创建 fluent 模式。

    public BaseControl
    {
        public void RenderControl(HTMLWriter writer) {}
    }
    
    public TextBox : BaseControl
    {
        public string Text { get;set; }
    }
    
    public static T TabIndex<T>(this T control, int index) where T : BaseControl {}
    

    有了上面的代码之后,你就可以像这样使用TabIndex来设置你想要的标签索引控件了。

    BaseControl control1 = new BaseControl();
    control1.TabIndex(1);
    
    // Moreover, you can use this for any devired controls like this
    TextBox control2 = new TextBox()
    {
        Text = "test"
    };
    
    // The following method still return TextBox control.
    control2.TabIndex(2);
    

    如您所见,您可以减少 BaseControl 类的不必要代码。但是你可以像我展示的那样改变它。这个概念适用于许多具有高耦合率的类。

    顺便说一句,我喜欢这种模式,因为它使我的代码易于阅读,就像下面的代码一样。

    var pmLogOnName = Html.CreatePopUpMenu("pmLogOnName")
                          .AddMenuItem("mLogOnName-RememberMe", "Remember UserName", isCheckBox: true, isSelected: true);
    
    Html.CreateTextBox("txtLogOnName", 1)
        .BindData(Model, x => x.LogOnName, "showError")
        .WaterMark(LogOnView.LogOnName)
        .BindMenu(pmLogOnName)
    

    【讨论】:

    • 听起来你想要一个 VB.Net With 块。
    【解决方案4】:

    在我看来,或者像上面那样的简单类(具有一些属性的类)不一定有很大的优势。这是一种不同的语义,一些开发人员一方面对此感到满意。另一方面,我认为它在 ASP.NET MVC 等某些领域非常有利......我使用 Telerik MVC 控件,它使用流畅的界面,并且设置控件非常好; MS方式需要使用集合和匿名类,使用起来不太方便。

    HTH。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 2013-07-30
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多