试图了解如何创建流畅的界面,以及何时使用它们

本文关键字:界面 何时使 了解 何创建 创建 | 更新日期: 2023-09-27 17:57:40

如何创建流畅的界面而不是更传统的方法?这是一种传统的方法:

接口:

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(); 

最后,这种情况适合流畅的界面吗?还是更传统的方法更有意义?

试图了解如何创建流畅的界面,以及何时使用它们

使接口流畅的关键是确保所有方法都返回接口本身的实例,或者返回一些其他对象,这些对象也实现了可以继续处理的接口。

因此,在您的情况下,每个IXmlDocumentFactory方法都必须返回一个IXmlDocumentFactory,以便您可以继续调用。如果有,最后一个方法会返回您真正想要的类型?

它使得代码可读性很强,但有一件事仍然让我有点犹豫,那个就是返回检查。你必须确保不能返回null,否则下一个"流畅调用"将失败。

在我看来有三件事很重要:

1.)有一个初始方法,它返回您将要使用的流畅界面

2.)类中实现fluent接口的每个方法都会返回自己,这样您就可以继续链接了——这些是真正的fluent方法

3.)有一个最终方法,它返回您真正想要构建的类型。

在您的例子中,由于您只有两个方法,所以它的边界很有用——通常在一个流畅的界面中会有更多的方法。或者(我个人更喜欢),您可以在API中提供两种选择:流畅的API和更传统的API(即具有可选参数)。

在你的情况下会这样做:

编辑以回应评论

public interface IXmlDocumentFactory<T>
{
    XmlDocument Create();                    //serializes just the data
    IXmlDocumentFactory<T> WithSchema(XmlSchema schema);    //serializes data and includes schema
}
public class DocumentFactory<T> : IXmlDocumentFactory<T>
{
    private XmlSchema _schema;
    private T _data;
    public DocumentFactory(T data)
    {
        _data = data;
    }
    public IXmlDocumentFactory<T> WithSchema(XmlSchema schema)
    {
        _schema = schema;
        return this;
    }
    public XmlDocument Create()
    {
        if (_schema != null)
        {
            //..use schema/data
            return new XmlDocument();
        }
        else //use data
            return new XmlDocument();
    }
    public static IXmlDocumentFactory<T> From(T data)
    {
        return new DocumentFactory<T>(data);
    }
}

然后你可以这样使用它:

var xmlDoc = DocumentFactory<int>.From(42)
                                 .WithSchema(new XmlSchema())
                                 .Create();
var xmlDoc = DocumentFactory<int>.From(42)
                                 .Create();

IMO,fluent API确实有其价值。流畅地配置一个组件感觉更像一个英语句子,从头到尾都很容易阅读。开发者的意图更容易理解。

有关实施示例,请参阅Autofac、Moq和Fluent NHibernate 等项目