方法链接的优点和缺点,以及通过对象本身替换所有void返回参数的可能性 [英] Benefits and drawbacks of method chaining and a possibility to replace all void return parameters by the object itself

查看:143
本文介绍了方法链接的优点和缺点,以及通过对象本身替换所有void返回参数的可能性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最感兴趣的是Java,但我认为这是一个普遍的问题。最近我一直在使用很多方法链接的Arquillian框架( ShrinkWrap )。方法链的其他示例是 StringBuilder StringBuffer 中的方法。使用这种方法有明显的好处:减少冗长度是其中之一。



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



我不是要求更改Java中的现有代码,这可能会在某处损坏,但是为什么不使用它会很好。我更从未来的框架(以Java编写)的设计角度询问。






我发现了一个类似的问题,但是原始的asker其实是想知道为什么它被认为是一个很好的做法:方法链接 - 为什么这是一个好的做法? / a>






虽然有一些答案可用,我仍然不知道什么是所有的好处和链接的缺点以及是否将所有的void方法链接起来都被认为是有用的。

解决方案

缺点




  • 主要是混淆了签名,如果有事情返回一个新的
    实例,我也不期望它作为一种变异方法。例如,如果
    a向量有一个缩放方法,那么如果它有一个返回值,我会假设
    它返回一个由输入缩放的新向量,如果不是,我将
    期望它另外当然,如果该类被扩展,那么你会遇到问题,通过链接你的对象被转换成一个超类型。当在父类中声明链接方法,但在子类的实例上使用链接方法时,会发生这种情况。






  • 它允许将数学方程式需要多个中间对象(导致不必要的开销),例如没有方法链接向量三叉乘积(作为随机示例)将必须写入

      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 Amit的解决方案是第一个答案使用多行方法链接,我把它作为第四个要素的一部分来完成。


I am mostly interested in Java, but I think it's a general question. Recently I've been working with Arquillian framework (ShrinkWrap) that uses a lot of method chaining. Other example of method chaining are methods in StringBuilder, StringBuffer. There are obvious benefits of using this approach: reduced verbosity is one of them.

Now I was wondering, why aren't all methods which have void return parameter implemented as chainable? There must be some obvious and objective drawback in chaining. Because if all methods are chainable, I can still choose not to use it.

I am not asking to change the existing code in Java, which might break something somewhere, but explanation why wasn't it used would be nice as well. I am more asking from a future framework (written in Java) design perspective.


I have found a similar question, but the original asker is actually wondering why it IS considered a good practice: Method chaining - why is it a good practice, or not?


While there are some answers available, I am still not sure what are all the benefits and drawbacks of chaining and whether it would be considered useful to have all void methods chainable.

解决方案

Drawbacks

  • Principally it confuses the signature, if something returns a new instance I don’t expect it to also be a mutator method. For example if a vector has a scale method then if it has a return I would presume it returns a new vector scaled by the input, if it doesn't then I would expect it to scale internally.
  • Plus of course you get problems if the class is extended, where partway through your chaining your object gets cast to a supertype. This occurs when a chaining method is declared in the parent class, but used on an instance of the child class.

Benefits

  • It allows mathematical equation style code to be written as full equations without the need for multiple intermediate objects (leading to unnecessary overhead), for example without method chaining the vector triple cross product (as a random example) would have to be written either as

    MyVector3d tripleCrossProduct=(vector1.multiply(vector2)).multiply(vector3);
    

    which has the disadvantage of creating an intermediate object which must be created and garbage collected, or

    MyVector3d tripleCrossProduct=vector1;
    tripleCrossProduct.multiplyLocal(vec2);
    tripleCrossProduct.multiplyLocal(vec3);
    

    which avoids the creation of intermediate objects but is deeply unclear, the variable name tripleCrossProduct is in fact a lie until line 3. However, if you have method chaining this can be written concisely in a normal mathematical way without creating unnecessary intermediate objects.

    MyVector3d tripleCrossProduct=vector1.multiplyLocal(vector2).multiplyLocal(vector3);
    

    All of this assumes that vector1 is sacrificial and will never need to be used again

  • And of course the obvious benefit; brevity. Even if your operations aren't linked in the manor of my above example you can still avoid unnecessary references to the object

    SomeObject someObject=new SomeObject();
    someObject
      .someOperation()
      .someOtherOperation();
    

NB MyVector3d is not being used as a real class of Java, but is assumed to perform the cross product when .multiply() methods are called. .cross() is not used so that the 'intention' is clearer to those not familiar with vector calculus
NB Amit's solution was the first answer to use multiline method chaining, I include it as part of the forth bullet point for completeness

这篇关于方法链接的优点和缺点,以及通过对象本身替换所有void返回参数的可能性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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