问题描述
昨天我发现,如果我像这样从每个方法返回类实例,就可以模拟一个流畅的接口.
I discovered yesterday that I can simulate a fluent interface if I return the class instance from each method like this...
public class IsThisFluent
{
public IsThisFluent Stuff()
{
//...
return this;
}
public IsThisFluent OtherStuff()
{
// ...
return this;
}
}
这就是全部吗?
我承认,我是一个头脑很小的熊,我想继续做下去,但是我认为最好与一个大人一起检查一下.
I admit, I'm a bear of very little brain and I want to carry on this this but I thought it might be best to check with a grown up.
我想念什么吗?
是否存在我没有用这种模式发现的陷阱"?
Is there a 'gotcha' that I haven't spotted with this pattern?
推荐答案
return this
并非全部有效.链接方法是构建流畅的API的一种简单形式,但是流畅的API通常看起来像DSL(特定于域的语言),并且很多很难设计.
return this
is not all there is to fluent interfaces.Chaining methods is a simplistic form of building a fluent API, but fluent APIs generally look like DSLs (domain specific languages) and are much, much harder to design.
以起订量为例:
new Mock<IInterface>()
.Setup(x => x.Method())
.CallBack<IInterface>(Console.WriteLine)
.Returns(someValue);
-
在类型
Mock<T>
上定义的Setup
方法返回ISetup<T, TResult>
的实例.The
Setup
method, defined on the typeMock<T>
, returns an instance ofISetup<T, TResult>
.为
ICallback<TMock, TResult>
定义的Callback
方法返回IReturnsThrows<TMock,TResult>
的实例.请注意,ISetup<T, TResult>
扩展了IReturnsThrows<TMock,TResult>
.The
Callback
method, defined forICallback<TMock, TResult>
returns an instance ofIReturnsThrows<TMock,TResult>
. Note thatISetup<T, TResult>
extendsIReturnsThrows<TMock,TResult>
.最后,在
IReturns<TMock,TResult>
上定义了Returns
并返回IReturnsResult<TMock>
.另请注意,IReturnsThrows<TMock,TResult>
扩展了IReturnsResult<TMock>
.Finally,
Returns
is defined onIReturns<TMock,TResult>
and returnsIReturnsResult<TMock>
. Also note thatIReturnsThrows<TMock,TResult>
extendsIReturnsResult<TMock>
.所有这些细微差别都会迫使您以特定的顺序调用这些方法,并禁止您连续两次调用
Setup
.或者在调用Setup
之前先调用Returns
.All these little nuances are there to force you to call these methods in a particular order, and to forbid you from calling
Setup
twice in a row, for example. Or from callingReturns
before you callSetup
.这些细节对于确保良好的用户体验非常重要.
These details are very important to ensure a good user experience.
要了解有关设计流畅接口的更多信息,请参阅Martin Fowler在 FluentInterface 上的文章. FluentAssertions 是设计可能变得多么复杂的又一个主要例子-而且结果的可读性更高
To read more on designing fluent interfaces, take a look at Martin Fowler's article on FluentInterface. FluentAssertions is another prime example of how complex the design might get - but also of how much more readable the outcome is.
这篇关于使我的课堂“流利"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!