有没有Fluent接口?

时间:2011-03-29 10:18:22

标签: fluent fluent-interface

我已经阅读了有关Fluent API的内容,其中代码可以像英文一样阅读,但我似乎无法找到它们的任何示例,因为我想知道它们是否是一种简单易懂的方法非全职程序员使用系统接口。有没有人有任何流畅的界面的例子?

5 个答案:

答案 0 :(得分:5)

下面的几个例子在C#中。非程序员使用?好吧,自己决定,我可能会说 - 可能不是 - 它们是为编码人员设计的,你需要知道语法。但是这是C#,在Ruby和其他语言中有更好的例子,具有更易读,类似英语的语法。

您可能还想查看外部DSLs(特定于域的语言)。 (流畅的API被视为内部DSL)。

NUnit的:

Assert.That(result, Is.EqualTo(10));

Ninject:

Bind<IDataAccess>()
                .To<Db4oDataAccess>()
                .WithConstructorArgument("fileName", "dbFile.db");

Rhino Mocks:

repository.Expect(x => x.LoadUserList()).Return(users);

以下是来自RSpec的一些Ruby:

@account.balance.should eql(Money.new(0, :dollars))

但是,请记住,这些示例是针对程序员的,如果非程序员是目标受众,则可能会获得更加人性化的代码,尤其是Ruby等。

答案 1 :(得分:2)

这是一个很好的例子:

http://www.google.com/codesearch/p?hl=en#CICsffyVkoc/trunk/src/ShouldIt.Clr/Fluent/Be.cs&q=lang:c%23%20Fluent&d=3

在开发自己的流畅界面或DSL(域特定语言)时,您应该做的是首先编写测试。写下你希望它如何表现的测试。

var q = Question.For(Site.StackOverflow)
           .WithTags("inteface", "fluent")
           .WithTitle("Are there any fluent interafces?");

然后开始编码。

答案 2 :(得分:2)

我是jOOQ的开发人员,它附带了一个流畅的API来动态构建类型安全的SQL查询。一个例子:

create.select(FIRST_NAME, LAST_NAME, count())
      .from(AUTHORS)
      .join(BOOKS)
      .using(AUTHOR_ID)
      .groupBy(FIRST_NAME, LAST_NAME)
      .orderBy(LAST_NAME);

底层SQL查询“隐藏”在许多接口背后,这些接口模拟了查询创建中涉及的每个“步骤”。这意味着,.select(Field...)返回一个提供对.from(Table)方法的访问权限的接口,该接口又返回一个提供.join(Table)方法访问权限的接口等。

SQL实际上是Java外部的DSL。使用jOOQ(或任何其他流畅的API),SQL可以在一定程度上“内化”到Java中。与外部DSL不同,某些特定于SQL的构造很难映射到Java中的内部DSL。一个例子是别名。

请点击此处查看更多文档:

http://www.jooq.org/manual/DSL/

<强>更新

与此同时,我实际上遇到了另一个非常有趣的流利API,用于从Java构建RTF文件。一些示例代码:

rtf().section(
   p( "first paragraph" ),
   p( tab(),
      " second par ",
      bold( "with something in bold" ),
      text( " and " ),
      italic( underline( "italic underline" ) )     
    )  
).out( out );

在此处查看更多信息:

http://code.google.com/p/jrtf/

答案 3 :(得分:1)

我为.NET创建了一个流畅的断言库:Should Assertion Library(向下滚动以查看流畅的示例)。

StructureMap有一个非常复杂的Fluent DSL用于配置。

FluentNHibernate非常好。它用流畅的DSL取代了基于XML的映射。

C#(和其他静态语言)对支持代码完成的Fluent API(例如Intellisense)有很好的优势,可以指导用户编写他们想要的内容。

无论如何,C#的缺点是语言残留阻碍了。例如,您经常会看到Should().Not.Be.Null()之类的内容,您希望看到Should.Not.Be.Null

答案 4 :(得分:0)

fluentAOP

  

允许实现的AOP(面向方面​​编程)库   使用流畅API的方面。 fluentAOP主要用于   简化了.NET中AOP的采用和使用。它不需要XML   文件,属性或任何其他类型的配置。与之相反   大多数AOP实现,其拦截语义完全依赖   强类型方法定义和流畅的API。

代码示例:

// Note: line indented to improve readability
var foo = new Proxy<Foo>()
   .Target( new Foo() )
   .InterceptMethod ( f => f.Go() )
   .OnBefore(()=> Console.Write(“Hello World!”) )
   .Save();

// Result: every time Go() is called a “Hello World!” message is previously printed.
foo.Go();

Should Assertion Library

  

The Should Assertion Library提供了一组扩展方法   测试AAA和BDD样式测试的断言。它提供断言   只是,因此它是Test runner不可知的。断言是一个   xUnit测试断言的直接fork。这个项目诞生了   因为测试运行者应该独立于断言!

代码示例:

var numbers = new List<int> { 1, 1, 2, 3 };
numbers.Should().Contain.Any(x => x == 1);
numbers
    .Should().Count.AtLeast(1)
    .Should().Count.NoMoreThan(5)
    .Should().Count.Exactly(4)
    .Should().Contain.One(x => x > 2);

Fluent Assertions

  

Fluent Assertions是一组允许您使用的.NET扩展方法   更自然地指定TDD或BDD风格的预期结果   测试。我们目前在所有内部和客户项目中都使用它   它被用于许多开源项目中。它运行在.NET 3.5,4.0和   4.5(桌面和Windows应用商店),Silverlight 4和5以及Windows Phon ......

代码示例:

var theObject = "whatever";
theObject.Should().BeOfType<String>("because a {0} is set", typeof(String));
theObject.Should().NotBeNull();

FluentValidation

  

.NET的一个小型验证库,它使用流畅的接口和lambda表达式为您的业务对象构建验证规则。

代码示例:

public CustomerValidator()
{
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}

TNValidate

  

TNValidate是.Net的流畅验证库。它使您能够   以某种类似于自然的方式编写验证逻辑   语言。这不仅仅是为了让它更容易一些   开发人员扫描,也意味着非程序员有更好的   能够理解和修改约束的机会   放在数据上。

代码示例:

// Basic validation.
Validate.That(Email, "Email address").IsEmail();

// Chaining a couple of rules.
Validate.That(Name, "Name").IsLongerThan(3).IsShorterThan(100);

Fluent.NET

  

Fluent.NET库引入了扩展方法,使.NET代码更易于阅读,更易于编写。

代码示例:

var x = Sequence.Create<int>(0, i => i);
var pair = KeyValuePair.Create(1, "Hello World");

var strings = new[] { "This", "is", "a" } .AsEnumerable();
strings = strings.With("test");

Fluent NHibernate

  

为NHibernate提供流畅,无XML,编译安全,自动,基于约定的映射。

代码示例:

public class CatMap : ClassMap<Cat>
{
  public CatMap()
  {
    Id(x => x.Id);
    Map(x => x.Name)
      .Length(16)
      .Not.Nullable();
    Map(x => x.Sex);
    References(x => x.Mate);
    HasMany(x => x.Kittens);
  }
}

Fluent Configuration API

  

可以以编程方式操作默认值   Enterprise Library用于核心的配置类,   检测和所有应用程序块。流利   企业库公开的界面旨在促进这一点   处理。流畅的界面可用于所有可配置的界面   仪器和所有企业库的功能   应用程序块,但验证和策略除外   注射应用程序块。

代码示例:

var builder = new ConfigurationSourceBuilder();

builder.ConfigureInstrumentation()
       .ForApplicationInstance("MyApp")
         .EnableLogging()
         .EnablePerformanceCounters();

Fluent Automation

  

简单,流畅的DSL,用于自动化Web应用程序。

代码示例:

Test.Run("KnockoutJS Cart Editor", I => {
    I.Open("http://knockoutjs.com/examples/cartEditor.html");
    I.Select("Motorcycles").From(".liveExample tr select:eq(0)"); // Select by value/text
    I.Select(2).From(".liveExample tr select:eq(1)"); // Select by index
    I.Enter(6).In(".liveExample td.quantity input:eq(0)");
    I.Expect.Text("$197.70").In(".liveExample tr span:eq(1)");

FluentDateTime

  

允许您编写更清晰的DateTime表达式和操作。

代码示例:

DateTime.Now - 1.Weeks() - 3.Days() + 14.Minutes();
DateTime.Now + 5.Years();
3.Days().Ago();
2.Days().Since(DateTime.Now);
DateTime.Now.NextDay();
DateTime.Now.NextYear();
DateTime.Now.PreviousYear();
DateTime.Now.WeekAfter();
DateTime.Now.Midnight();
DateTime.Now.Noon();
DateTime.Now.SetTime(11, 55, 0);