知乎周源微信_每周源代码14-Fluent接口版

知乎周源微信

知乎周源微信

iStock_000000237891XSmall5

If you're new to this, each week I post some snippets of particularly interesting (read: beautiful, ugly, clever, obscene) source and the project it came from. This started from a belief that reading source is as important (or more so) as writing it. We read computer books to become better programmers, but unless you're reading books like Programming Pearls, you ought to peruse some Open Source projects for inspiration.

如果您是新手,我每周都会发布一些片段,这些片段特别有趣(阅读:美丽,丑陋,聪明,淫秽)和其来源。 这源于一种信念,即阅读源与编写源同样重要(甚至更重要) 。 我们阅读计算机书籍以成为更好的程序员,但是除非您阅读《 Programming Pearls》之类的书,否则您应该细读一些开放源代码项目以获取灵感。

And so, Dear Reader, I present to you fourteenth in a infinite number of posts of "The Weekly Source Code." Here's some source I was reading this week.

因此,尊敬的读者,我每周源代码的无数帖子中向您展示了第十四位。 这是我本周正在阅读的一些资料。

Over the last year or so I've seen an increase in discussion around so-called "fluent interfaces" in many languages. The addition of extension methods (mixins) to C# 3.0 has caused a flood of interesting (weird?) interface as we as a collective to attempt to make programming as easy as writing prose.

在过去的一年左右的时间里,我已经看到围绕多种语言的所谓“流利接口”的讨论有所增加。 在C#3.0中添加扩展方法(混合)会引起大量有趣的界面(怪异的?),因为我们集体试图使编程像编写散文一样容易。

Martin Fowler talked about this in 2005 after a workshop with Eric Evans when they first named them "fluent interfaces." He gives this example:

Martin Fowler在2005年Eric Evans举行的一次研讨会上谈到了这一点,当时他们首次将它们命名为“流畅的界面”。 他举了这个例子:

The simplest example is probably from Eric's timeAndMoney library. To make a time interval in the usual way we might see something like this:

最简单的示例可能来自Eric的timeAndMoney库。 为了以通常的方式设置时间间隔,我们可能会看到以下内容:

TimePoint fiveOClock, sixOClock;
...
TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);


  
 TimePoint fiveOClock, sixOClock;
...
TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);

The timeAndMoney library user would do it this way:

timeAndMoney库用户将通过以下方式进行操作:

   TimeInterval meetingTime = fiveOClock.until(sixOClock);

Of course, the ubiquitous Ruby example is

当然,无处不在的Ruby示例是

20.minutes.ago

20分钟前

Martin makes a great point when trying to put "fluent" APIs in a common OOP context, like that of an object browser with emphasis mine:

当试图将“流利的” API放在常见的OOP上下文中时,例如在强调我的对象浏览器的情况下, Martin提出了一个很好的观点:

One of the problems of methods in a fluent interface is that they don't make much sense on their own. Looking at a method browser of method by method documentation doesn't show much sense to with. Indeed sitting there on its own I'd argue that it's a badly named method that doesn't communicate its intent at all well. It's only in the context of the fluent action that it shows its strengths. One way around this may be to use builder objects that are only used in this context. - Martin Fowler

流利的界面中方法的问题之一是它们本身并没有多大意义。 纵观通过方法的文档方法的方法浏览器没有显示太大的意义with 确实,独自一人坐在那儿我会认为这是一个名字不好的方法,根本无法传达其意图。 只有在流畅的操作中才能显示出自己的优势。 解决此问题的一种方法可能是使用仅在此上下文中使用的构建器对象。 -马丁·福勒

Piers Cawley follows up and offers a number of guidelines for use when one is designing these things. See his post for the complete annotated list.

Piers Cawley跟进并提供了一些在设计这些东西时使用的准则。 有关完整的注释列表,请参见他的帖子

  1. Hide your working.

    隐藏你的工作。

  2. Keep your state to yourself.

    保持自己的状态。

  3. Think really hard about names.

    认真思考名字。

  4. Take advantage of your implementation language.

    利用您的实现语言。

  5. If you have them, blocks are you friends.

    如果有它们,街区就是您的朋友。

  6. Test first design can be a useful way of exploring what your interface should be.

    测试优先设计可能是探索界面应该是什么的有用方法。

  7. Reasonable defaults.

    合理的默认值。

In the .NET space, Ayende's Rhino Mocks are, I think, the first and best example before LINQ that really got it right with syntax like.

在.NET领域中,我认为Ayende的Rhino Mocks是LINQ之前第一个也是最好的示例,该示例使用诸如此类的语法确实使它正确。

  Expect
.Call(mock.GetID(1))
.IgnoreArguments()
.Repeat
.Once()
.Return(something);

Similar things are done in Java with their support for mixins, called Static Imports in Java 5.

在Java中,它们对混合包的支持完成了类似的工作,在Java 5中称为“静态导入”

When fluent interfaces get larger and more complex, they suddenly get called Domain Specific Languages as Peirs points out. But, a true DSL is even easier and might not be fluent at all, but rather customized to the domain:

当流畅的界面变得更大,更复杂时,正如Peirs指出的那样它们突然被称为“领域特定语言” 。 但是,真正的DSL甚至更容易并且可能一点也不流利,而是针对域进行了定制:

"It seems that every time someone writes a Ruby library that uses class methods, symbols and hashes reasonably sensibly they get delusions of grandeur and call the result a Domain Specific Language (or maybe an ‘embedded’ DSL)."

“看来,每当有人编写一个合理地使用类方法,符号和哈希的Ruby库时,他们都会感到妄想,并将结果称为领域特定语言(或可能是“嵌入式” DSL)。”

Two good examples of libraries as DSLs with some fluent aspects are Why's Hpricot, an HTML Parser for Ruby that looks like this:

两个很好的方面,例如DSL方面的DSL库,为什么是Hpricot ,它是用于RubyHTML解析器,看起来像这样:

 #!ruby
 require 'hpricot'
 require 'open-uri'
 # load the RedHanded home page
 doc = Hpricot(open("http://redhanded.hobix.com/index.html"))
 # change the CSS class on links
 (doc/"span.entryPermalink").set("class", "newLinks")
 # remove the sidebar
 (doc/"#sidebar").remove
 # print the altered HTML
 puts doc

And Python's Beautiful Soup, also an HTML Parser.

还有Python的Beautiful Soup,也是HTML解析器。

 from BeautifulSoup import BeautifulSoup, Tag
 soup = BeautifulSoup("Argh!FooBlah!")
 tag = Tag(soup, "newTag", [("id", 1)])
 tag.insert(0, "Hooray!")
 soup.a.replaceWith(tag)
 print soup
 # Argh!
   
   
    
    Hooray!
   
   Blah!

Back on the C# side, Garry Shutler is creating more fluent assertions using extension methods and lambdas for MBUnit like:

回到C#方面, Garry Shutler使用扩展方法和MBUnit的lambda创建更流畅的断言,例如:

testObject.ShouldBeTheSameObjectAs(targetObject).And.ShouldBeEqualTo(testObject).And.ShouldSatisfy(x => x is Object);

testObject.ShouldBeTheSameObjectAs(targetObject).And.ShouldBeEqualTo(testObject).And.ShouldSatisfy(x => x是Object);

But what's a DSL and what's a Fluent Interface and what's just an API? Martin adds in 2006 (as he continues to write his DSL Book):

但是什么是DSL?什么是Fluent接口?什么才是API? 马丁在2006年补充道(他继续编写DSL Book):

For me, a key element is that DSLs are limited both in scope (they refer to a particular domain) and capability (they lack features that are basic for general purpose languages). As a result good DSLs are usually small and simple: hence terms like 'little languages' and 'mini-languages'.

对我而言,一个关键因素是DSL在范围(它们指的是特定域)和功能(它们缺乏通用语言的基本功能)方面都受到限制。 结果,好的DSL通常小而简单:因此,诸如“小语言”和“小语言”之类的术语。

For internal DSLs, the fuzzy boundary is what is an API and what is a DSL. Fundamentally there is no difference, an internal DSL is just an API with a fancy name (as the old Bell labs saying goes: "library design is language design"). Despite this, however, I think there is a different feel when you are working with an API that's written with a DSL feel. Things like a FluentInterface can make working with an API a qualitatively different experience. Thinking in DSL terms makes you think about readability in a different way, exploiting the syntax of the host language to create something that seems to stand on its own - rake is a great example of this. - Martin Fowler

对于内部DSL,模糊边界是什么是API,什么是DSL。 从根本上讲,两者没有什么区别,内部DSL只是一个名字很漂亮的API(就像古老的贝尔实验室所说的那样:“库设计就是语言设计”)。 尽管如此,我认为当您使用以DSL方式编写的API时会有不同的感觉。 FluentInterface之类的东西可以使使用API​​产生质的不同体验。 用DSL术语进行思考可以使您以不同的方式考虑可读性,利用宿主语言的语法来创建似乎可以独立存在的内容-rake是一个很好的例子。 -马丁·福勒

Even scripting languages like PHP are getting on board with fluent interfaces, assuming that "with" in this context makes sense to you.

即使脚本语言(如PHP)也可以使用流畅的界面,前提是在这种情况下使用“ with”对您有意义。

<?php
private function makeFluent(Customer $customer) {
    $customer->  newOrder()
         ->with(6, 'TAL')
         ->with(5, 'HPK')->skippable()
         ->with(3, 'LGV')
         ->priorityRush();           

Ultimately I think Paul Jones nails it when he says "Fluent Interfaces Require Fluent Situations":

最终,我认为保罗·琼斯(Paul Jones)说“流利的界面需要流利的情境”时就钉牢了

"I think, for a fluent interface to be effective, you need situations where you actually have all that information at one time so that you can chain the methods in a fluid way" - Paul M. Jones

“我认为,要使一个流畅的界面有效,您需要同时实际拥有所有信息的情况,以便您可以以一种流畅的方式链接这些方法。”-Paul M. Jones

Scott Bellware said matter of factly:

Scott Bellware说的是事实,

"Whether fluent interface is a form of DSL or not, it's obviously a form of fluent interface." - Scott Bellware

“流畅接口是否是DSL的一种形式,显然是流畅接口的一种形式。” -Scott Bellware

Are you exploring Fluent Interfaces?

您在探索Fluent接口吗?

Shameless Plug: As an aside, one addition thing I'd like to mention is our little Forums over at http://hanselman.com/forum. They are run on excellent JitBit's AspNetForum application, the "little forum that could" in my opinion. There's lots of interesting discussions on many diverse topics, and you can look at just the most recent posts, and every page has an RSS Feed.

无耻的插件:顺便说一句,我想提到的另一件事是我们位于http://hanselman.com/forum上的小论坛。 它们在出色的JitBit的AspNetForum应用程序上运行,我认为这是“可能的小论坛”。 关于许多不同主题,有很多有趣的讨论,并且您可以查看最新的帖子,并且每个页面都有一个RSS Feed。

翻译自: https://www.hanselman.com/blog/the-weekly-source-code-14-fluent-interface-edition

知乎周源微信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值