有没有流畅接口?

4

我了解流畅API,它可以使代码像英语一样易读,但我似乎找不到任何示例。我想知道它们是否是一种合理的方式,通过非全职程序员创建易于使用的系统界面。有人有流畅接口的示例吗?

5个回答

5
以下是几个C#的示例。是否适用于非程序员?嗯,你可以自己决定,我认为可能不太适合——它们设计给开发人员使用,需要了解语法。但这毕竟是C#,在Ruby和其他语言中有更易读、类似英语的语法。
您可能还想查看外部DSL(特定领域语言)链接。(流畅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 等语言中,可以获得更易读的代码。


2

谢谢提供链接,但我没有找到API的描述。 - yazzapps.com
链接已经失效。这是该项目现在的地址:https://github.com/erichexter/Should/blob/master/src/Should.Fluent/Model/Be.cs - Tim Scott

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/


1

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

StructureMap拥有非常复杂的Fluent DSL配置。

FluentNHibernate相当不错。它使用流畅的DSL替换了基于XML的映射。

C#(和其他静态语言)在支持流畅API方面具有很好的优势,支持代码完成(例如Intellisense),以指导用户通过组合他们想要的内容。

然而,C#的缺点是语言繁琐。例如,您经常会看到像Should().Not.Be.Null()这样的东西,而您更希望看到Should.Not.Be.Null


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断言库

Should断言库为AAA和BDD风格的测试提供了一组扩展方法。它仅提供断言,并且因此与测试运行器无关。这些断言是xUnit测试断言的直接分支。该项目的诞生是因为测试运行器应该独立于断言!

代码示例:

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

流畅断言

流畅断言是一组.NET扩展方法,允许您更自然地指定TDD或BDD样式测试的预期结果。我们目前在所有内部和客户项目中使用它,在许多开源项目中也使用它。它运行在.NET 3.5、4.0和4.5(桌面和Windows Store)、Silverlight 4和5以及Windows Phon...

代码示例:

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

FluentValidation

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

流畅的NHibernate

流畅、无需XML、编译安全、自动化、基于约定的NHibernate映射。

代码示例:

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

流畅的配置 API

可以通过编程方式操作 Enterprise Library 用于核心、仪表板和所有应用程序块的默认配置类。Enterprise Library 提供的流畅接口旨在促进此过程。流畅接口可用于仪表板的所有可配置功能以及除验证和策略注入应用程序块之外的所有 Enterprise Library 应用程序块。

代码示例:

var builder = new ConfigurationSourceBuilder();

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

流畅自动化

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

代码示例:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接