方法链是我所知道的构建流畅接口(interface)的唯一方法。
这是一个 C# 示例:
John john = new JohnBuilder()
.AddSmartCode("c#")
.WithfluentInterface("Please")
.ButHow("Dunno");
Assert.IsNotNull(john);
[Test]
public void Should_Assign_Due_Date_With_7DayTermsVia_Invoice_Builder()
{
DateTime now = DateTime.Now;
IInvoice invoice = new InvoiceBuilder()
.IssuedOn(now)
.WithInvoiceNumber(40)
.WithPaymentTerms(PaymentTerms.SevenDays)
.Generate();
Assert.IsTrue(invoice.DateDue == now.AddDays(7));
}
那么其他人如何创建流畅的界面呢?你如何创建它?需要什么语言/平台/技术?
最佳答案
构建流畅界面背后的核心思想之一是可读性 - 阅读代码的人应该能够理解所实现的内容,而不必深入研究实现来澄清细节。
在现代面向对象语言(例如 C#、VB.NET 和 Java)中,方法链接是实现此目的的一种方法,但它不是唯一的技术 - 其他两种技术是工厂类和命名参数。
另请注意,这些技术并不相互排斥 - 目标是最大限度地提高代码的可读性,而不是方法的纯粹性。
方法链
方法链背后的关键见解是永远不要有返回 void 的方法,而是始终返回某个对象,或更常见的是某个接口(interface),以允许进行进一步的调用。
您不一定需要返回调用该方法的同一对象 - 也就是说,您并不总是需要“return this;”。
一个有用的设计技术是创建一个内部类 - 我总是在它们后面加上“Expression”后缀 - 公开流畅的 API,允许配置另一个类。
这有两个优点 - 它将流畅的 API 保留在一处,与类的主要功能隔离,并且(因为它是一个内部类)它可以以其他类无法做到的方式修补主类的内部结构.
您可能想要使用一系列接口(interface)来控制开发人员在给定时间点可以使用哪些方法。
工厂类
有时您想要构建一系列相关对象 - 示例包括 NHibernate Criteria API、Rhino.Mocks 期望约束和 NUnit 2.4 的新语法。
在这两种情况下,您都拥有要存储的实际对象,但为了使它们更容易创建,有工厂类提供静态方法来制造您需要的实例。
例如,在 NUnit 2.4 中您可以编写:
Assert.That( result, Is.EqualTo(4));
“Is”类是一个静态类,充满了工厂方法,这些方法为 NUnit 的评估创建约束。
事实上,为了考虑 float 的舍入误差和其他不精确性,您可以指定测试的精度:
Assert.That( result, Is.EqualTo(4.0).Within(0.01));
(提前道歉 - 我的语法可能有问题。)
命名参数
在支持它们的语言(包括 Smalltalk 和 C# 4.0)中,命名参数提供了一种在方法调用中包含附加“语法”的方法,从而提高了可读性。
考虑一个假设的 Save() 方法,该方法采用文件名以及保存后应用于文件的权限:
myDocument.Save("sampleFile.txt", FilePermissions.ReadOnly);
使用命名参数,此方法可能如下所示:
myDocument.Save(file:"SampleFile.txt", permissions:FilePermissions.ReadOnly);
或者,更流畅地说:
myDocument.Save(toFile:"SampleFile.txt", withPermissions:FilePermissions.ReadOnly);
关于language-agnostic - 流畅的接口(interface) - 方法链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/293353/