流畅的界面在Delphi中 [英] Fluent interface in Delphi

查看:105
本文介绍了流畅的界面在Delphi中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Delphi中使用流利的界面有什么优缺点?

What are the pros and cons in using fluent interfaces in Delphi?

流畅的界面应该增加可读性,但是我有点怀疑,有一个长的LOC包含很多链接的方法。

Fluent interfaces are supposed to increase the readability, but I'm a bit skeptical to have one long LOC that contains a lot of chained methods.

是否有任何编译器问题?

是否有任何调试问题?

是否有任何运行时/错误处理问题?

Are there any compiler issues?
Are there any debugging issues?
Are there any runtime/error handling issues?

流畅的界面用于例如 TStringBuilder THTMLWriter TGpFluentXMLBuilder

Fluent interfaces are used in e.g. TStringBuilder, THTMLWriter and TGpFluentXMLBuilder.

更新:

David Heffernan问我关心的问题关于。我已经给出了一些想法,整体问题是明确规定它的完成与让编译器决定如何完成之间的区别。

Updated:
David Heffernan asked which issues I was concerned about. I've been given this some thought, and the overall issue is the difference between "explicitly specifying how it's done" versus "letting the compiler decide how it's done".

AFAICS没有关于编译器如何实际处理链接方法的文档,也没有关于编译器如何处理链接方法的任何规范。

AFAICS, there is no documentation on how chained methods actually is handled by the compiler, nor any specification on how the compiler should treat chained methods.

本文,我们可以看到编译器如何将两个附加的var参数添加到声明为函数的方法中,标准调用约定将三个参数放在寄存器中,下一个在栈中。具有2个参数的流利函数方法将使用堆栈,而具有2个参数的普通过程方法仅使用寄存器。

In this article we can read about how the compiler adds two additional var-parameters to methods declared as functions, and that the standard calling convention puts three params in the register and the next ones on the stack. A "fluent function method" with 2 params will therefor use the stack, whereas an "ordinary procedure method" with 2 params only uses the register.

我们也知道编译器有一些魔法来优化二进制文件(例如,字符串作为函数结果, a href =http://stackoverflow.com/questions/3054526/delphi-compiler-directive-to-evaluate-arguments-in-reverse/3054899#3054899>评估订单, ref to local proc ),但有时会令人惊讶的副作用为程序员。

We also know that the compiler does some magic to optimize the binary (e.g. string as function result, evaluation order, ref to local proc), but sometimes with surprising side effects for the programmer.

所以事实上,内存/堆栈/注册管理更加复杂,而且编译器可以用无意的副作用来做一些魔法的事实是非常臭的我。因此,这个问题。

So the fact that the memory/stack/register-management is more complex and the fact that compiler could do some magic with unintentional side effects, is pretty smelly to me. Hence the question.

在我阅读了答案(很好的)后,我的关注被大大减少,但是我的偏好依然是一样的:)

After I've read the answers (very good ones), my concern is strongly reduced but my preference is still the same :)

推荐答案

编译器问题

使用接口(而不是对象),链中的每个调用将导致引用计数开销,即使完全相同的接口一直返回,编译器也无法知道它。因此,您将生成一个更大的代码,并且复杂的堆栈。

If you're using interfaces (rather than objects), each call in the chain will result in a reference count overhead, even if the exact same interface is returned all the time, the compiler has no way of knowing it. You'll thus generate a larger code, with a more complex stack.

调试问题

调用链被视为单个指令,您不能在中间步骤上进行步骤或断点。您也不能评估中间步骤的状态。
调试中间步骤的唯一方法是在asm视图中进行跟踪。
调试器中的调用堆栈也不会清楚,如果在流畅的链中发生多次相同的方法。

The call chain being seen as a single instruction, you can't step or breakpoint on the intermediate steps. You also can't evaluate state at intermediate steps. The only way to debug intermediate steps is to trace in the asm view. The call stack in the debugger will also not be clear, if the same methods happens multiple times in the fluent chain.

运行时问题: / strong>

Runtime issues:

当使用链接(而不是对象)时,您必须支付引用计数开销以及更复杂的异常帧。
你不能在链中尝试结束,所以不能保证关闭在流畅链中打开的内容。

When using interfaces for the chain (rather than objects), you have to pay for the reference counting overhead, as well as a more complex exception frame. You can't have try..finally constructs in a chain, so no guarantee of closing what was opened in a fluent chain f.i.

调试/错误日志记录问题:

异常及其堆栈跟踪将链接视为单个指令,因此如果您在.DoSomething中崩溃,并且调用链有几个.DoSomething电话,你不知道是哪个导致了这个问题。

Exceptions and their stack trace will see the chain as a single instruction, so if you crashed in .DoSomething, and the call chain has several .DoSomething calls, you won't know which caused the issue.

代码格式化问题:

AFAICT现有的代码格式化程序都不会正确地布局流畅的呼叫链,所以它只是手动格式化,可以保持流畅的呼叫链可读。如果运行一个自动格式化程序,它通常会将链条变成可读性混乱。

AFAICT none of the existing code formatters will properly layout a fluent call chain, so it's only manual formatting that can keep a fluent call chain readable. If an automated formatter is run, it'll typically turn a chain into a readability mess.

这篇关于流畅的界面在Delphi中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆