方法链是对象方法返回对象本身以便调用结果的做法另一种方法。 像这样:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
这似乎被认为是一个很好的实践,因为它产生可读的代码,或“流畅的界面”。 然而,对我来说,它似乎破坏了面向对象本身隐含的对象调用符号 - 生成的代码并不代表对先前方法的结果执行操作,这就是面向对象代码的方式通常期望起作用:
participant.getSchedule('monday').saveTo('monday.file')
这种差异设法为“调用结果对象”的点表示法创建两种不同的含义:在链接的上下文中,上面的示例将被理解为保存参与者对象,即使该示例实际上旨在保存 getSchedule 接收到的调度对象。
我知道这里的区别在于被调用的方法是否应该返回某些内容(在这种情况下它将返回被调用的对象本身以进行链接)。 但这两种情况无法从符号本身区分,只能从被调用方法的语义区分。 当不使用方法链接时,我总是可以知道方法调用对与前一个调用的结果相关的东西进行操作 - 使用链接,这个假设就被打破了,我必须在语义上处理整个链了解被调用的实际对象到底是什么。 例如:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
最后两个方法调用引用 getSocialStream 的结果,而前面的调用引用参与者。 也许在上下文发生变化的地方实际编写链是不好的做法(是吗?),但即便如此,您也必须不断检查看起来相似的点链实际上是否保留在相同的上下文中,或者只对结果起作用。
在我看来,虽然方法链表面上确实产生了可读的代码,但重载点符号的含义只会导致更多的混乱。 由于我不认为自己是编程大师,所以我认为错误是我的。 那么:我错过了什么? 我对方法链的理解是否有误? 在某些情况下方法链接特别好,或者在某些情况下特别糟糕?
旁注:我理解这个问题可以被解读为掩盖为问题的意见陈述。 然而事实并非如此——我真的想理解为什么链接被认为是好的实践,以及我认为它破坏了固有的面向对象表示法的错误在哪里。
Method chaining is the practice of object methods returning the object itself in order for the result to be called for another method. Like this:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
This seems to be considered a good practice, since it produces readable code, or a "fluent interface". However, to me it instead seems to break the object calling notation implied by the object orientation itself - the resulting code does not represent performing actions to the result of a previous method, which is how object oriented code is generally expected to work:
participant.getSchedule('monday').saveTo('monday.file')
This difference manages to create two different meanings for the dot-notation of "calling the resulting object": In the context of chaining, the above example would read as saving the participant object, even though the example is in fact intended to save the schedule object received by getSchedule.
I understand that the difference here is whether the called method should be expected to return something or not (in which case it would return the called object itself for chaining). But these two cases are not distinguishable from the notation itself, only from the semantics of the methods being called. When method chaining is not used, I can always know that a method call operates on something related to the result of the previous call - with chaining, this assumption breaks, and I have to semantically process the whole chain to understand what the actual object being called really is. For example:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
There the last two method calls refer to the result of getSocialStream, whereas the ones before refer to the participant. Maybe it's bad practice to actually write chains where the context changes (is it?), but even then you'll have to constantly check whether dot-chains that look similar are in fact keep within the same context, or only work on the result.
To me it appears that while method chaining superficially does produce readable code, overloading the meaning of the dot-notation only results in more confusion. As I don't consider myself a programming guru, I assume the fault is mine. So: What am I missing? Do I understand method chaining somehow wrong? Are there some cases where method chaining is especially good, or some where it's especially bad?
Sidenote: I understand this question could be read as a statement of opinion masked as a question. It, however, isn't - I genuinely want to understand why chaining is considered good practice, and where do I go wrong in thinking it breaks the inherent object-oriented notation.
发布评论
评论(20)
只是我的2分钱;
方法链接使调试变得棘手:
- 你不能把断点放在一个简洁的点上,这样你就可以在你想要的地方暂停程序
- 如果这些方法之一抛出异常,并且您得到行号,则您不知道“链”中的哪个方法导致了问题。
我认为总是写出非常短而简洁的行通常是一个很好的做法。 每一行应该只调用一个方法。 喜欢更多的线路而不是更长的线路。
编辑:评论提到方法链接和换行是分开的。 那是真实的。 不过,根据调试器的不同,可能会也可能不会在语句中间放置断点。 即使可以,使用带有中间变量的单独行也可以为您提供更大的灵活性,并且您可以在“监视”窗口中检查一大堆值,这有助于调试过程。
Just my 2 cents;
Method chaining makes debugging tricky:
- You can't put the breakpoint in a concise point so you can pause the program exactly where you want it
- If one of these methods throws an exception, and you get a line number, you have no idea which method in the "chain" caused the problem.
I think it's generally good practice to always write very short and concise lines. Every line should just make one method call. Prefer more lines to longer lines.
EDIT: comment mentions that method chaining and line-breaking are separate. That is true. Depending on the debugger though, it may or may not be possible to place a break point in the middle of a statement. Even if you can, using separate lines with intermediate variables gives you a lot more flexibility and a whole bunch of values you can examine in the Watch window that helps the debugging process.
我同意这是主观的。 在大多数情况下,我避免方法链接,但最近我还发现了一种情况,它是正确的事情 - 我有一个方法接受大约 10 个参数,并且需要更多参数,但大多数时候你只需要指定一个很少。 通过覆盖,这很快变得非常麻烦。 相反,我选择了链接方法:
方法链接方法是可选的,但它使编写代码变得更容易(尤其是使用 IntelliSense)。 请注意,这是一个孤立的案例,并不是我的代码中的一般做法。
关键是 - 在 99% 的情况下,如果没有方法链接,您可能可以做得同样好甚至更好。 但对于 1% 的人来说,这是最好的方法。
I agree that this is subjective. For the most part I avoid method chaining, but recently I also found a case where it was just the right thing - I had a method which accepted something like 10 parameters, and needed more, but for the most time you only had to specify a few. With overrides this became very cumbersome very fast. Instead I opted for the chaining approach:
The method chaining approach was optional, but it made writing code easier (especially with IntelliSense). Mind you that this is one isolated case though, and is not a general practice in my code.
The point is - in 99% cases you can probably do just as well or even better without method chaining. But there is the 1% where this is the best approach.
就我个人而言,我更喜欢仅作用于原始对象的链接方法,例如设置多个属性或调用实用程序类型的方法。
在我的示例中,当一个或多个链接方法返回除 foo 之外的任何对象时,我不会使用它。 虽然从语法上讲,只要对链中的对象使用正确的 API,就可以链接任何内容,但恕我直言,更改对象会降低可读性,并且如果不同对象的 API 有任何相似之处,可能会造成真正的混乱。 如果您在最后执行一些非常常见的方法调用(
.toString()
、.print()
,等等),您最终将针对哪个对象进行操作? 随意阅读代码的人可能不会发现它将是链中隐式返回的对象而不是原始引用。链接不同的对象也可能导致意外的空错误。 在我的示例中,假设 foo 有效,所有方法调用都是“安全的”(例如,对 foo 有效)。 在OP的示例中:
...不能保证(作为查看代码的外部开发人员)getSchedule实际上会返回一个有效的非空调度对象。 此外,调试这种类型的代码通常要困难得多,因为许多 IDE 不会在调试时将方法调用评估为您可以检查的对象。 IMO,任何时候您可能需要一个对象来检查以进行调试,我更喜欢将其放在显式变量中。
Personally, I prefer chaining methods that only act on the original object, e.g. setting multiple properties or calling utility-type methods.
I do not use it when one or more of the chained methods would return any object other than foo in my example. While syntactically you can chain anything as long as you are using the correct API for that object in the chain, changing objects IMHO makes things less readable and can be really confusing if the APIs for the different objects have any similarities. If you do some really common method call at the end (
.toString()
,.print()
, whatever) which object are you ultimately acting upon? Someone casually reading the code might not catch that it would be an implicitly returned object in the chain rather than the original reference.Chaining different objects can also lead to unexpected null errors. In my examples, assuming that foo is valid, all the method calls are "safe" (e.g., valid for foo). In the OP's example:
...there's no guarantee (as an outside developer looking at the code) that getSchedule will actually return a valid, non-null schedule object. Also, debugging this style of code is often a lot harder since many IDEs will not evaluate the method call at debug time as an object that you can inspect. IMO, anytime you might need an object to inspect for debugging purposes, I prefer to have it in an explicit variable.
Martin Fowler 在这里进行了很好的讨论:
Martin Fowler has a good discussion here:
在我看来,方法链有点新颖。 当然,它看起来很酷,但我没有看到它有任何真正的优点。
怎么样:
比什么更好:
例外可能是当 addObject() 返回一个新对象时,在这种情况下,未链接的代码可能会有点麻烦,例如:
编辑:我对此的看法在过去 10 年里发生了变化。 对于可变对象,我仍然没有看到太多好处,尽管它对于避免一点点重复很有用。 但现在我更喜欢不变性,方法链接是我进行非破坏性更新的首选方式,我一直使用这种方式。
In my opinion, method chaining is a bit of a novelty. Sure, it looks cool but I don't see any real advantages in it.
How is:
any better than:
The exception might be when addObject() returns a new object, in which case the unchained code may be a little more cumbersome like:
Edit: My opinions on this have changed over the last 10 years. For mutable objects, I still don't see a lot of benefit, although it is useful for avoiding a little bit of duplication. But now that I favour immutability a lot more, method chaining is my preferred way of doing non-destructive updates, which I use all the time.
这是危险的,因为您可能依赖比预期更多的对象,就像您的调用返回另一个类的实例一样:
我将举一个例子:
foodStore 是一个由您拥有的许多食品商店组成的对象。
foodstore.getLocalStore() 返回一个对象,该对象保存距离参数最近的商店的信息。 getPriceforProduct(anything) 是该对象的方法。
因此,当您调用 foodStore.getLocalStore(parameters).getPriceforProduct(anything) 时,
您不仅依赖于 FoodStore,还依赖于 LocalStore。
如果 getPriceforProduct(anything) 发生变化,您不仅需要更改 FoodStore,还需要更改调用链式方法的类。
您应该始终以类之间的松散耦合为目标。
话虽这么说,我个人喜欢在 Ruby 编程时将它们链接起来。
It is dangerous because you may be depending on more objects than expected, like then your call returns an instance of another class:
I will give an example:
foodStore is an object that is composed of many food stores you own.
foodstore.getLocalStore() returns an object that holds information on the closest store to the parameter. getPriceforProduct(anything) is a method of that object.
So when you call foodStore.getLocalStore(parameters).getPriceforProduct(anything)
you are depending not only on FoodStore as you though, but also on LocalStore.
Should getPriceforProduct(anything) ever changes, you need to change not only FoodStore but also the class that called the chained method.
You should always aim for loose coupling among classes.
That being said, i personally like to chain them when programming Ruby.
许多人使用方法链作为一种方便的形式,而不是考虑任何可读性问题。 如果方法链涉及对同一个对象执行相同的操作,那么它是可以接受的 - 但前提是它确实增强了可读性,而不仅仅是为了编写更少的代码。
不幸的是,许多人按照问题中给出的示例使用方法链接。 虽然它们仍然可读,但不幸的是它们导致了多个类之间的高度耦合,因此这是不可取的。
Many use method chaining as a form of convenience rather than having any readability concerns in mind. Method chaining is acceptable if it involves performing the same action on the same object - but only if it actually enhances readability, and not just for writing less code.
Unfortunately many use method chaining as per the examples given in the question. While they can still be made readable, they are unfortunately causing high coupling between multiple classes, so it's not desirable.
方法链可以允许直接在 Java 中设计高级 DSL。 本质上,您至少可以对这些类型的 DSL 规则进行建模:
这些规则可以使用这些接口来实现
通过这些简单的规则,您可以直接在 Java 中实现复杂的 DSL,例如 SQL,就像 jOOQ,我创建的一个库。 请参阅取自 我的博客在这里:
另一个很好的例子是jRTF,有点DSL 设计用于直接用 Java 生成 RTF 文档。 一个例子:
Method chaining can allow for designing advanced DSLs in Java directly. In essence, you can model at least these types of DSL rules:
These rules can be implemented using these interfaces
With these simple rules, you can implement complex DSL's such as SQL directly in Java, as is done by jOOQ, a library that I have created. See a rather complex SQL example taken from my blog here:
Another nice example is jRTF, a little DSL designed for cerating RTF documents directly in Java. An example:
链接的好处
即,我喜欢使用它的地方
我没有看到提及的链接的一个好处是能够在变量初始化期间或将新对象传递给方法时使用它,不确定这是否是不好的做法。
我知道这是人为的示例,但假设您有以下类,
并说您无权访问基类,或者说默认值是动态的,基于时间等。是的,您可以实例化,然后更改值但这可能会变得很麻烦,特别是如果您只是将值传递给方法时:
但这不是更容易阅读吗:
或者,类成员怎么样?
vs
这就是我使用链接的方式,通常我的方法仅用于配置,因此它们只有 2 行长,设置一个值,然后
Return Me
。 对我们来说,它已经将难以阅读和理解的大行代码清理成一行,读起来就像一个句子。类似于
Vs 的东西
链接的损害
即,在我不喜欢使用它的地方,
当有很多参数要传递给例程时,我不使用链接,主要是因为行变得很长,并且正如OP提到的,当你'重新调用其他类的例程以传递给链接方法之一。
还担心例程会返回无效数据,因此到目前为止,我仅在返回被调用的同一实例时才使用链接。 正如所指出的,如果在类之间进行链接,则会增加调试难度(哪一个返回 null?),并且会增加类之间的依赖耦合。
结论
就像生活中的一切和编程一样,链接既不好也不坏,如果您可以避免不好的事情,那么链接可以带来很大的好处。
我尝试遵守这些规则。
链接
当
Benefits of Chaining
ie, where I like to use it
One benefit of chaining that I did not see mentioned was the ability to use it during variable initiation, or when passing a new object to a method, not sure if this is bad practice or not.
I know this is contrived example but say you have the following classes
And say you don't have access to the base class, or Say the default values are dynamic, based on time, etc. Yes you could instantiate then, then change the values but that can become cumbersome, especially if you're just passing the values to a method:
But isn't this just much easier to read:
Or, what about a class member?
vs
This is how I've been using chaining, and typically my methods are just for configuration, so they are only 2 lines long, set a value, then
Return Me
. For us it has cleaned up huge lines very hard to read and understand code into one line that read like a sentence.something like
Vs Something like
Detriment Of Chaining
ie, where I don't like to use it
I don't use chaining when there are a lot of parameters to pass to the routines, mainly because the lines get very long, and as the OP mentioned it can get confusing when you're calling routines to other classes to pass to one of the chaining methods.
There is also the concern that a routine would return invalid data, thus so far I've only used chaining when I'm returning the same instance being called. As was pointed out if you chain between classes you make debuging harder (which one returned null?) and can increase dependencies coupling among classes.
Conclusion
Like everything in life, and programming, Chaining is neither good, nor bad if you can avoid the bad then chaining can be a great benefit.
I try to follow these rules.
chaining
routine
这似乎有点主观。
在我看来,方法链接本身并不是坏事或好事。
可读性是最重要的。
(还要考虑到,如果发生变化,链接大量方法会使事情变得非常脆弱)
This seems kinda subjective.
Method chaining is not soemthing that is inherently bad or good imo.
Readability is the most important thing.
(Also consider that having large numbers of methods chained will make things very fragile if something changes)
我通常讨厌方法链接,因为我认为它会降低可读性。 紧凑性经常与可读性混淆,但它们不是同一个术语。 如果您在一条语句中完成所有操作,那么这会很紧凑,但大多数情况下,它的可读性(更难遵循)比在多个语句中执行的要差。 正如您所注意到的,除非您不能保证所使用方法的返回值相同,否则方法链将成为混乱的根源。
1.)
vs
2.)
vs
3.)
vs
正如你所看到的,你几乎什么也没赢,因为你必须在单个语句中添加换行符以使其更具可读性,并且你必须添加缩进以表明你正在谈论不同的对象。 好吧,如果我想使用基于标识的语言,那么我会学习 Python 而不是这样做,更不用说大多数 IDE 都会通过自动格式化代码来删除缩进。
我认为这种链接唯一有用的地方是 CLI 中的管道流或 SQL 中将多个查询连接在一起。 两者都有多个语句的价格。 但是,如果您想解决复杂的问题,即使付出代价并使用变量在多个语句中编写代码或编写 bash 脚本和存储过程或视图,您最终也会遇到这样的情况。
正如 DRY 的解释:“避免知识的重复(而不是文本的重复)。” 和“少打字,甚至不要重复文本。”,第一个原则的真正含义是什么,但第二个是常见的误解,因为很多人无法理解过于复杂的废话,例如“每条知识都必须有一个单一的,明确的,系统内的权威代表”。 第二个是不惜一切代价的紧凑性,在这种情况下会破坏,因为它会降低可读性。 当您在有界上下文之间复制代码时,第一种解释会被 DDD 打破,因为松散耦合在这种情况下更为重要。
I generally hate method chaining because I think it worsens readability. Compactness is often confused with readability, but they are not the same terms. If you do everything in a single statement then that is compact, but it is less readable (harder to follow) most of the times than doing it in multiple statements. As you noticed unless you cannot guarantee that the return value of the used methods are the same, then method chaining will be a source of confusion.
1.)
vs
2.)
vs
3.)
vs
As you can see you win close to nothing, because you have to add line breaks to your single statement to make it more readable and you have to add indentation to make it clear that you are talking about different objects. Well if I'd want to use an identation based language, then I would learn Python instead of doing this, not to mention that most of the IDEs will remove the indentation by auto formatting the code.
I think the only place where this kind of chaining can be useful is piping streams in CLI or JOINing multiple queries together in SQL. Both have a price for multiple statements. But if you want to solve complex problems you will end up even with those paying the price and writing the code in multiple statements using variables or writing bash scripts and stored procedures or views.
As of the DRY interpretations: "Avoid the repetition of knowledge (not the repetition of text)." and "Type less, don't even repeat texts.", the first one what the principle really means, but the second one is common misunderstanding because many people cannot understand overcomplicated bullshit like "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system". The second one is compactness at all cost, which breaks in this scenario, because it worsens readability. The first interpretation breaks by DDD when you copy code between bounded contexts, because loose coupling is more important in that scenario.
对于大多数情况来说,方法链可能只是一个新鲜事物,但我认为它有它的地位。 可以在 CodeIgniter 的 Active Record 使用 中找到一个示例:
这看起来更干净(并且在我看来,这更有意义)比:
它确实是主观的; 每个人都有自己的看法。
Method chaining may simply be a novelty for most cases but I think it has it's place. One example might be found in CodeIgniter's Active Record use:
That looks a lot cleaner (and makes more sense, in my opinion) than:
It really is subjective; Everyone has their own opinion.
我认为主要的谬误是认为这是一种面向对象的方法,而实际上它更多的是一种函数式编程方法而不是其他方法。
我使用它的主要原因是为了提高可读性并防止我的代码被变量淹没。
当其他人说这会损害可读性时,我真的不明白他们在说什么。 这是我使用过的最简洁、最有凝聚力的编程形式之一。
另外:
convertTextToVoice.LoadText("source.txt").ConvertToVoice("destination.wav");
是我通常使用它的方式。 我通常不使用它来链接 x 个参数。 如果我想在方法调用中放入 x 个参数,我将使用 params 语法:
public void foo(params object[] items)
并根据对象进行强制转换根据类型或仅使用数据类型数组或集合,具体取决于您的用例。
I think the primary fallacy is thinking this is an object oriented approach in general when in fact it is more of a functional programming approach than anything else.
The main reasons I use it is for both readability and preventing my code from being inundated by variables.
I don't really understand what others are talking about when they say it damages readability. It is one of the most concise and cohesive form of programming I have used.
Also this:
convertTextToVoice.LoadText("source.txt").ConvertToVoice("destination.wav");
is how I would typically use it. Using it to chain x number of parameters is not how I typically use it. If I wanted to put in x number of parameters in a method call I would use the params syntax:
public void foo(params object[] items)
And cast the objects based on type or just use a datatype array or collection depending on your use case.
我同意,因此我改变了在我的库中实现流畅界面的方式。
之前:
之后:
在“之前”实现中,函数修改了对象并以
return this
结束。我更改了实现返回相同类型的新对象。
我对此更改的理由:
返回值与函数无关,它纯粹是为了支持链接部分,根据 OOP,它应该是一个 void 函数。
系统库中的方法链也以这种方式实现(如 linq 或 string):
原始对象保持不变,允许 API 用户决定如何处理它。 它允许:
复制实现也可以用于构建对象:
其中
setBackground(color)
函数更改实例并且不返回任何内容(就像它应该的那样)。函数的行为更加可预测(参见第 1 点和第 2 点)。
使用短变量名还可以减少代码混乱,而无需在模型上强制使用 api。
结论:
在我看来,使用
return this
实现的流畅接口是错误的。I agree, I therefor changed the way an fluent interface was implemented in my library.
Before:
After:
In the "before" implementation the functions modified the object and ended in
return this
.I changed the implementation to return a new object of the same type.
My reasoning for this change:
The return value had nothing to do with the function, it was purely there to support the chaining part, It should have been a void function according to OOP.
Method chaining in system libraries also implement it that way (like linq or string):
The original object remains intact, allowing the API user to decide what to do with it. It allows for:
A copy implementation can also be used for building objects:
Where the
setBackground(color)
function changes the instance and returns nothing (like its supposed to).The behavior of the functions are more predicable (See point 1 & 2).
Using a short variable name can also reduce code-clutter, without forcing a api on the model.
Conclusion:
In my opinion a fluent interface that uses an
return this
implementation is just wrong.自以为是的答案
链接的最大缺点是,读者可能很难理解每个方法如何影响原始对象(如果会影响),以及每个方法返回什么类型。
一些问题:
在大多数语言中,使用链接确实会使调试变得更加困难。 即使链中的每个步骤都在自己的行上(这违背了链接的目的),也很难检查每个步骤之后返回的值,特别是对于非变异方法。
根据语言和编译器的不同,编译时间可能会更慢,因为解析表达式可能要复杂得多。
我相信,就像所有事情一样,链接是一个很好的解决方案,在某些情况下可以很方便。 应谨慎使用,了解其含义,并将链元素的数量限制在少数。
Opinionated Answer
The biggest drawback of chaining is that it can be hard for the reader to understand how each method affects the original object, if it does, and what type does every method return.
Some questions:
Debugging, in most languages, can indeed be harder with chaining. Even if each step in the chain is on its own line (which kind of defeats the purpose of chaining), it can be hard to inspect the value returned after each step, specially for non-mutating methods.
Compile times can be slower depending on the language and compiler, as expressions can be much more complex to resolve.
I believe that like with everything, chaining is a good solution that can be handy in some scenario. It should be used with caution, understanding the implications, and limiting the number of chain elements to a few.
优点:
坏处:
一般:
一个好的方法是一般不要使用链接,除非出现情况或特定模块特别适合它。
在某些情况下,链接可能会严重损害可读性,尤其是在权衡第 1 点和第 2 点时。
有时它可能会被滥用,例如代替另一种方法(例如传递数组)或以奇怪的方式混合方法(parent.setSomething() .getChild().setSomething().getParent().setSomething())。
The good:
The bad:
General:
A good approach is to not use chaining in general until situations arise or specific modules would be particularly suited to it.
Chaining can hurt readability quite severely in some cases especially when weighing in point 1 and 2.
On accasation it can be misused, such as instead of another approach (passing an array for example) or mixing methods in bizarre ways (parent.setSomething().getChild().setSomething().getParent().setSomething()).
这里完全忽略的一点是,方法链允许DRY 。 它是“with”的有效替代(在某些语言中实现得很差)。
这与 DRY 始终很重要的原因相同; 如果A结果出错,而这些操作需要在B上执行,则只需更新1处,而不是3处。
实际上,在这种情况下优势很小。 不过,少一点打字,多一点健壮(DRY),我会接受的。
The totally missed point here, is that method chaining allows for DRY. It's an effective stand-in for the "with" (which is poorly implemented in some languages).
This matters for the same reason DRY always matters; if A turns out to be an error, and these operations need to be performed on B, you only need to update in 1 place, not 3.
Pragmatically, the advantage is small in this instance. Still, a little less typing, a litle more robust (DRY), I'll take it.
在类型化语言(缺少 auto 或等效语言)中,这使实现者不必声明中间结果的类型。
对于较长的链,您可能会处理几种不同的中间类型,您需要声明它们中的每一个。
我相信这种方法确实是在 Java 中开发的,其中 a) 所有函数调用都是成员函数调用,b) 需要显式类型。 当然,这里需要进行权衡,失去一些明确性,但在某些情况下,有些人发现这是值得的。
In typed languages (that lack
auto
or equivalent) this saves the implementer from having to declare the types of the intermediate results.For longer chains you might be dealing with several different intermediate types, you'd need to declare each of them.
I believe that this approach really developed in Java where a) all function calls are member function invocations, and b) explicit types are required. Of course there is a trade-off here in terms, loosing some explicitness, but in some situations some people find it worth while.
Linq 查询是方法链接的一个很好的示例,其中典型的查询如下所示:
在我看来,这是非常直观的,并且避免了不必要的临时变量来存储人们可能几乎不感兴趣的部分结果。
需要注意的一件更微妙的事情是“ThenBy”扩展方法的使用,只有在调用“OrderBy”或“OrderByDescending”方法之后才能调用该方法。 这意味着这里还维护一个内部状态,它决定是否可以调用 thenBy。 就像在此查询中一样,在某些情况下,客户端应用程序可能对将内部状态存储在临时变量中不感兴趣,而可能只对最终结果感兴趣。
因此,在编写库时,如果我们想要提供一个 API,让其感觉按特定顺序执行一组特定操作,那么允许方法链接将使库的使用更加直观。
Linq queries are a good example of method chaining, where a typical query looks like the following:
In my opinion, this is quite intuitive and avoids unnecessary temporary variables to store partial results which one may be hardly interested in.
One subtler thing to notice is the usage of the "ThenBy" extension method, which is available to be called only after a call to an "OrderBy" or "OrderByDescending" method. That means an internal state is also maintained here which determines whether a ThenBy can be called or not. And like in this query, there are cases where the client application may not be interested in storing the internal state in a temporary variable, but may only be interested in the final results.
So, while writing a library if we want to provide an API that gives a sense of performing a certain set of operations in a certain order, then allowing method chaining would make the usage of the library much more intuitive.
嗯,我认为方法链接的一个最重要的优点是您不必不断重复调用同一对象来执行连续操作。
你必须使用它。
Well, I see one most important advantage of method chaining is You don't have to keep repeating calls to same object for doing consecutive operations.
You must use it.