首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >方法链的优缺点和用对象本身替换所有空返回参数的可能性

方法链的优缺点和用对象本身替换所有空返回参数的可能性
EN

Stack Overflow用户
提问于 2013-06-07 04:19:43
回答 9查看 15.4K关注 0票数 24

我主要对Java感兴趣,但我认为这是一个普遍的问题。最近,我一直在使用Arquillian (ShrinkWrap),它使用了很多方法链接。方法链接的其他例子是StringBuilderStringBuffer中的方法。使用这种方法有明显的好处:减少冗长是其中之一。

现在我在想,为什么不是所有具有void返回参数的方法都实现为可链接的呢?链条一定有一些明显的、客观的缺点。因为如果所有的方法都是链式的,我仍然可以选择不使用它。

我并不是要求修改Java中现有的代码,这可能会在某个地方破坏一些东西,但是解释为什么不使用它也很好。我更多的是从未来的框架(用Java编写)设计的角度来问这个问题。

我发现了一个类似的问题,但是最初的提问者实际上想知道为什么它被认为是一个很好的实践:方法链接-为什么它是一个良好的实践,或不?

虽然有一些可用的答案,但我仍然不确定链接的所有优点和缺点,以及是否认为将所有的无效方法都链接起来是有用的。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2013-06-07 09:04:21

缺点

  • 主要是它混淆了签名,如果某个东西返回一个新实例,我不希望它也是一个mutator方法。例如,如果一个向量有一个刻度方法,那么如果它有一个返回,我会假设它返回一个由输入缩放的新向量,如果它没有,那么我会期望它在内部缩放。
  • 当然,如果类是扩展的,那么当然会出现问题,在这个类中,通过链接对象的过程会被转换成一个超级类型。当在父类中声明链接方法但在子类的实例上使用时,就会发生这种情况。

福利

  • 它允许将数学方程样式的代码写成完整的方程,而不需要多个中间对象(导致不必要的开销),例如,如果没有方法链接矢量三叉积(作为随机示例),则必须将其编写为 MyVector3d tripleCrossProduct=(vector1.multiply(vector2)).multiply(vector3); 它的缺点是创建一个必须创建和垃圾收集的中间对象,或者 MyVector3d tripleCrossProduct=vector1;tripleCrossProduct.multiplyLocal(vec2);tripleCrossProduct.multiplyLocal(vec3); 这避免了中间对象的创建,但是非常不清楚,变量名tripleCrossProduct实际上是第3行之前的谎言。但是,如果您有方法链接,则可以用正常的数学方法简洁地编写,而无需创建不必要的中间对象。 MyVector3d tripleCrossProduct=vector1.multiplyLocal(vector2).multiplyLocal(vector3); 所有这些都假设vector1是牺牲的,再也不需要使用了。
  • 当然,最明显的好处是简洁。即使您的操作在我上面的示例中没有链接,您仍然可以避免对对象的不必要引用。 SomeObject someObject=new SomeObject();someObject .someOperation() .someOtherOperation();

NB MyVector3d并不是作为Java的真实类使用,而是假设在调用.multiply()方法时执行跨产品。不使用.cross()是为了使那些不熟悉向量演算的人更清楚“意图”。

NB的解决方案是第一个使用多行方法链接的答案,我把它作为完整的第四个要点的一部分。

票数 26
EN

Stack Overflow用户

发布于 2013-06-13 12:53:58

方法链接是实现fluent接口的一种方法,而不管编程语言是什么。它的主要优点(可读的代码)告诉您什么时候使用它。如果对可读的代码没有特别的需求,最好避免使用它,除非API自然地设计为返回方法调用的结果的上下文/对象。

第1步: Fluent接口与命令查询API

对于命令查询API,必须考虑使用Fluent接口.为了更好地理解它,让我为下面的命令查询API编写一个项目列表定义。简单地说,这只是一种标准的面向对象的编码方法:

  • 修改数据的方法称为Command。命令不返回值。
  • 返回值的方法称为Query。查询不修改数据。

遵循命令查询API将给您带来如下好处:

  • 看一下面向对象的代码,你就会明白发生了什么。
  • 代码的调试更容易,因为每个调用都是单独进行的。

步骤2:基于命令查询API的Fluent接口

但是命令查询API由于某种原因而存在,而且它确实读起来更好。那么,我们如何同时使用fluent接口和命令查询API呢?

回答:必须在命令查询API之上实现fluent接口(而不是用fluent接口替换命令查询API )。将fluent接口看作是命令查询API上的外观。毕竟,它被称为fluent“接口”--在标准(命令查询) API之上的一个可读的或方便的接口。

通常,在命令查询API准备好之后(编写,可能是单元测试,抛光以便于调试),您可以在上面编写一个流畅的界面软件层。换句话说,fluent接口通过使用命令查询API来完成其功能.然后,在任何您想要方便和可读性的地方使用fluent接口(带有方法链接)。然而,一旦您想了解实际发生的事情(例如,调试异常时),就可以一直深入了解命令查询API --良好的旧的面向对象代码。

票数 25
EN

Stack Overflow用户

发布于 2013-06-07 05:57:20

我发现使用方法链接的缺点是在发生NullPointerException或任何其他Exception时调试代码。假设您有以下代码:

String test = "TestMethodChain"; test.substring(0,10).charAt(11); //This is just an example

然后,在执行上述代码时,您将得到超出范围的字符串索引:异常。当您进入实时情况时,这样的事情发生了,那么您就得到了发生了哪些行错误,而不是链式方法的哪个部分导致了这一错误。因此,在知道数据总是会出现或错误被正确处理的地方,需要谨慎地使用它。

它也有其优点,比如不需要编写多行代码并使用多个变量。

许多框架/工具都使用这种方法,比如Dozer,当我过去调试代码时,我必须仔细查看链的每个部分,以找出导致错误的原因。

希望这能有所帮助。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16976150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档