尝试了解如何创建流畅的界面以及何时使用它们
如何创建一个流畅的界面而不是更传统的方法?这是一种传统方法:
界面:
interface IXmlDocumentFactory<T>
{
XmlDocument CreateXml() //serializes just the data
XmlDocument CreateXml(XmlSchema schema) //serializes data and includes schema
}
interface IXmlSchemaFactory<T>
{
XmlSchema CreateXmlSchema() //generates schema dynamically from type
}
用法:
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlDocument = xmlDocFactory.CreateXml();
//or...
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlSchemaFactory = new XmlSchemaFactory<Foo>();
var xmlDocument = xmlDocFactory.CreateXml(xmlSchemaFactory.CreateXmlSchema());
我希望能够说:
var xmlDocument = new XmlDocumentFactory<Foo>(foo).CreateXml().IncludeSchema();
//or...
var xmlDocument = new XmlDocumentFacotry<Foo>(foo).CreateXml();
最后,这种情况适合流畅的界面吗?或者更传统的方法会更有意义吗?
How would one create a fluent interface instead of a more tradition approach? Here is a traditional approach:
Interface:
interface IXmlDocumentFactory<T>
{
XmlDocument CreateXml() //serializes just the data
XmlDocument CreateXml(XmlSchema schema) //serializes data and includes schema
}
interface IXmlSchemaFactory<T>
{
XmlSchema CreateXmlSchema() //generates schema dynamically from type
}
Usage:
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlDocument = xmlDocFactory.CreateXml();
//or...
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlSchemaFactory = new XmlSchemaFactory<Foo>();
var xmlDocument = xmlDocFactory.CreateXml(xmlSchemaFactory.CreateXmlSchema());
I'd like to be able to say:
var xmlDocument = new XmlDocumentFactory<Foo>(foo).CreateXml().IncludeSchema();
//or...
var xmlDocument = new XmlDocumentFacotry<Foo>(foo).CreateXml();
Lastly, is this situation a good fit for fluent interfaces? Or would a more traditional approach make more sense?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使接口流畅的关键是确保方法都返回接口本身的实例,或者也实现可以继续处理的接口的其他对象。
因此,在您的情况下,每个 IXmlDocumentFactory 方法都必须返回 IXmlDocumentFactory,以便您可以继续调用。最后一个方法(如果有的话)返回您真正想要的类型?
它使得代码非常可读,但仍然让我有点不安的一件事是返回检查。您必须非常确保不能返回空值,否则下一个“流畅调用”将会失败。
The key to making an interface fluent is to ensure the methods all return instances of the interface itself, or some other object that also implements the interface that can continue the processing.
So in your case each of your IXmlDocumentFactory methods has to return an IXmlDocumentFactory so you can continue to call. The final method, if there is one, returns the type you really want?
It makes for very readable code but one thing that still gives me a bit of the willies is return-checking. You have to make very sure that null's can't be returned or else the next 'fluent call' will fail.
在我看来,三件事很重要:
1.) 有一个初始方法,它返回您将要使用的流畅接口
2.) 类中实现流畅接口的每个方法都会返回自身,因此你可以继续链接 - 这些是真正的流畅的方法。
3.) 有一个最终方法返回您真正想要构建的类型。
在您的示例中,由于您只有两种方法,因此它的边界很有用 - 通常您会在流畅的界面中拥有更多方法。或者(我个人更喜欢),您可以在 API 中提供两个选项:流畅的 API 和更传统的 API(即带有可选参数)。
在你的情况下会做这样的事情:
编辑以回复评论。
然后你可以像这样使用它:
Three things are important in my mind:
1.) There is an initial method that returns the fluent interface you are going to work with
2.) Each method in the class that implements your fluent interface returns itself so you can continue chaining - these are the real fluent methods.
3.) There is a final method that returns the type that you really want to build.
In your example since you only have two methods, its borderline useful - usually you would have more methods in a fluent interface. Alternatively (which I personally prefer) you can offer both options in your API: A fluent API and a more traditional API (i.e. with optional parameters).
In your case would do something like this:
Edited to respond to comment.
Then you can use it like this:
在我看来,流畅的 API 确实有其价值。流畅地配置组件感觉更像是英文句子,从头到尾都很容易阅读。开发者的意图更容易被理解。
有关实现示例,请参考诸如 Autofac、Moq 和 Fluent NHibernate >
IMO, fluent APIs do have their value. Fluently configuring a component feels more like an English sentence, easily read from start to finish. The intent of a developer is more easily comprehended.
For examples of implementation, please refer to such projects as Autofac, Moq and Fluent NHibernate