有 Fluent 接口吗?

发布于 2024-10-27 19:29:26 字数 1436 浏览 2 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

↘紸啶 2024-11-03 19:29:26

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

您可能还想查看外部 DSL(域特定语言)。 (Fluent 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 和之类的。

Couple of examples below in C#. Used by non-programmers? Well, decide for yourself, I'd say probably not - they're designed for coders and you need to know the syntax. But then this is C#, there are better examples in Ruby and other languages with much more readable, english-like syntax.

You'd might want to also look at external DSLs (domain specific languages). (Fluent APIs are considered internal DSLs).

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

Here's some Ruby from RSpec:

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

However, bear in mind that these examples are aimed at programmers, it is possible to get much more human-readable code if non-programmers are the target audience, especially with Ruby and the like.

那些过往 2024-11-03 19:29:26

我是 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) 方法的访问的接口,该方法又返回一个提供对 .from(Table) 方法的访问的接口。 code>.join(Table)方法等。SQL

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

请在此处查看更多文档:

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

<更新:

与此同时,我实际上遇到了另一个非常有趣的 Fluent 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/

I am the developer of jOOQ, which ships with a fluent API to dynamically construct typesafe SQL queries. An example:

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

The underlying SQL query is "hidden" behind a number of interfaces that model every "step" involved in query creation. This means, .select(Field...) returns an interface providing access to the .from(Table) method, which in turn returns an interface providing access to the .join(Table) method, etc.

SQL is actually a DSL which is external to Java. With jOOQ (or any other fluent API), SQL can be "internalised" into Java to a certain extent. Unlike with an external DSL, some SQL-specific constructs are hard to be mapped to an internal DSL in Java. An example for this is aliasing.

See more documentation here:

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

Update:

In the mean time, I actually ran across another highly interesting fluent API used to construct RTF files from Java. Some example code:

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

See more here:

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

怼怹恏 2024-11-03 19:29:26

这是一个很好的示例:

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

然后开始编码。

Here is a pretty good example:

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

What you should do when developing your own fluent interface or DSL (Domain Specific Language) as it also is called, is to write tests first. Write tests on how you want it to behave.

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

And then start coding away.

不甘平庸 2024-11-03 19:29:26

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

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

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

C#(和其他静态语言)对于 Fluent API 来说有一个非常好的优势,即支持代码完成(例如 Intellisense)来指导用户编写他们想要的内容。

无论如何,C# 的缺点是语言的缺陷会阻碍。例如,您经常会看到诸如 Should().Not.Be.Null() 之类的内容,而您更愿意看到 Should.Not.Be.Null

I created a library of fluent assertions for .NET: Should Assertion Library (scroll down to see the fluent examples).

StructureMap has a very sophisticated Fluent DSL for configuration.

FluentNHibernate is pretty good. It replaces XML based mapping with a fluent DSL.

C# (and other static languages) have a very nice advantage for Fluent APIs of supporting code completion (e.g. Intellisense) to guide the user through composing what they intend.

The downside, with C# anyway, is that language cruft gets in the way. For example, you will often see things like Should().Not.Be.Null() where you would rather see Should.Not.Be.Null.

抹茶夏天i‖ 2024-11-03 19:29:26

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 Assertion 库提供了一组扩展方法
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);

流畅断言

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

代码示例:

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

流畅、无 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);
  }
}

Fluent 配置 API

可以通过编程方式操纵默认值
企业库使用的核心配置类,
仪器和所有应用程序块。流利的
企业库公开的接口旨在促进这一点
过程。流畅的界面可用于所有可配置的
仪器和所有企业库的功能
应用程序块(验证和策略除外)
注射应用块。

代码示例:

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

fluentAOP

An AOP (Aspect-Oriented Programming) library that allows to implement
aspects utilizing a fluent API. fluentAOP is primarily designed to
simplify the adoption and use of AOP in .NET. It does not require XML
files, attributes or any other kind of configuration. In contrast to
most AOP implementations, its interception semantics exclusively rely
on strongly-typed method definitions and a fluent API.

Code example:

// 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 provides a set of extension methods for
test assertions for AAA and BDD style tests. It provides assertions
only, and as a result it is Test runner agnostic. The assertions are a
direct fork of the xUnit test assertions. This project was born
because test runners Should be independent of the the assertions!

Code example:

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 is a set of .NET extension methods that allow you to
more naturally specify the expected outcome of a TDD or BDD-style
test. We currently use it in all our internal and client projects, and
it is used in many open-source projects. It runs on .NET 3.5, 4.0 and
4.5 (Desktop and Windows Store), Silverlight 4 and 5 and Windows Phon…

Code example:

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

FluentValidation

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects.

Code example:

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 is a fluent validation library for .Net. It enables you to
write validation logic in a way that somewhat resembles natural
language. This is not only intended to make it a little easier for
developers to scan, but also means non-programmers have a better
chance of being able to understand and modify the constraints being
placed on data.

Code example:

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

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

Fluent.NET

The Fluent.NET library introduces extension methods to make .NET code easier to read and more fluid to write.

Code example:

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

Fluent, XML-less, compile safe, automated, convention-based mappings for NHibernate.

Code example:

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

It is possible to programmatically manipulate the default
configuration classes used by Enterprise Library for the core,
instrumentation, and all of the application blocks. The fluent
interface exposed by Enterprise Library is designed to facilitate this
process. The fluent interface can be used for all of the configurable
features of instrumentation and for all of the Enterprise Library
application blocks with the exception of the Validation and Policy
Injection Application Blocks.

Code example:

var builder = new ConfigurationSourceBuilder();

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

Fluent Automation

Simple, fluent DSL for automating web applications.

Code example:

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

Allows you to write cleaner DateTime expressions and operation.

Code example:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文