我昨天发现如果从这样的每个方法返回类实例,我可以模拟一个流畅的接口...
public class IsThisFluent
{
public IsThisFluent Stuff()
{
//...
return this;
}
public IsThisFluent OtherStuff()
{
// ...
return this;
}
}
这就是它的全部吗?
我承认,我是一只脑力很小的熊,我想继续这个,但我认为最好与成年人一起检查。
我错过了什么吗?
我有没有发现过这种模式的“陷阱”?
答案 0 :(得分:3)
几乎就是这样。
这是一篇非常好的文章: http://rrpblog.azurewebsites.net/?p=33
我也非常喜欢这个答案的例子: 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);
这提醒我,我现在需要一杯咖啡。
答案 1 :(得分:2)
return this
不是 all 有流畅的界面。
链接方法是构建流畅API的简单形式,但流畅的API通常看起来像DSL(特定于域的语言),并且很多,很多难以设计。
以Moq为例:
new Mock<IInterface>()
.Setup(x => x.Method())
.CallBack<IInterface>(Console.WriteLine)
.Returns(someValue);
在Setup
类型上定义的Mock<T>
方法返回ISetup<T, TResult>
的实例。
为Callback
定义的ICallback<TMock, TResult>
方法返回IReturnsThrows<TMock,TResult>
的实例。请注意,ISetup<T, TResult>
扩展了IReturnsThrows<TMock,TResult>
。
最后,Returns
上定义IReturns<TMock,TResult>
并返回IReturnsResult<TMock>
。另请注意,IReturnsThrows<TMock,TResult>
扩展了IReturnsResult<TMock>
。
所有这些细微差别都会迫使您按特定顺序调用这些方法,并禁止您连续两次调用Setup
,例如。或者在致电Returns
之前致电Setup
。
这些细节对于确保良好的用户体验非常重要。
要阅读有关设计流畅界面的更多信息,请参阅Martin Fowler关于FluentInterface的文章。 FluentAssertions是设计可能带来多么复杂的另一个主要例子 - 但也是结果的可读性有多大。
答案 2 :(得分:0)
不,那就是它。
背后的想法是,您可以将方法调用链接在一起操纵内部状态。最终Fluent interface的主要目标是可读性,LINQ是一个非常好的例子。