传递整个对象与传递对象的属性

时间:2014-01-15 11:28:51

标签: java performance oop

我正在考虑我的应用程序的解决方案。下面是这样的情况:我有一个类,其方法将ObjectA作为输入参数并调用几个小方法,这些方法中的每一个都需要ObjectA的某些部分(它们不重叠,即method1()需要{ {1}}和ObjectA.field1ObjectA.field2需要method2()等等......)现在问题是:鉴于一般良好的代码实践和性能,最好将ObjectA传递给每个这些方法之一,所以他们可以自己提取他们需要的价值,或者更好的只是传递他们的价值观?我的意思是:

ObjectA.field3

method1(ObjectA);
method2(ObjectA);

感谢您的回答!

4 个答案:

答案 0 :(得分:32)

请注意,使用您的代码,您实际上并未传递ObjectA。也就是说,您将引用类型传递给ObjectA,因此在性能注释中,传递String对象引用和ObjectA对象引用之间的差异可以忽略不计。

我写的方式

如果方法与类相关,我会传递整个对象。我的理由是尽可能地分散课堂知识。我的意思是以下几点。

public void doSomethingRelatedToTheClass(String param)
{
    // Do something with param.
}

我在这里的第一个批评是这种方法假设输入是正确的字段。我的第二个,现在,调用此代码的类需要更多地了解这个方法,因为它必须像这样调用它:

doSomethingRelatedToTheClass(myObject.getValue());

这意味着,如果您发现ObjectA的其他成员在此方法中工作得更好,或者您想要访问ObjectA的其他成员,并且您将doSomething()更改为反映这一变化,您还需要将方法调用更改为:

doSomethingRelatedToTheClass(myObject.getOtherValue(), myObject.getValue());

因此,通过传入整个对象,您将该细节抽象出来,并且该方法可以处理它;即:

doSomethingRelatedToTheClass(myObject); // Doesn't need to know what you do with it.

public void doSomethingRelatedToTheClass(ObjectA object)
{
    String val = object.getValue();

    String otherVal = object.getOtherValue();
}

当对一个类进行更改时,会导致其他类发生更改,这是一个名为Shotgun Surgery的反模式。

修改

我有机会在这里查看我的答案,我稍微修改了原来的答案,因为我认为它不是所有情况的最佳解决方案。如上所述,如果一个方法与一个类具体相关,那么该类的实例(或更优选地,它的超类或实现的接口[s])应该是参数。

不是这种情况的时间是功能可以是通用的。泛型函数的示例可能是:

public String[] findNouns(String sentence);

在这种情况下,在句子中查找名词可能适用于大量用例,而不仅仅是您定义的用例。因此,传递值是唯一合理的方法,否则,您将两个逻辑耦合在一起,没有直接关系。名词的发现和你定义的任意对象。

摘要

  • 如果方法是与对象相关的逻辑,则传入对象

  • 如果该方法与该对象无关,并且该对象仅将其用作实用程序函数,则传入该值并将该函数命名为。

答案 1 :(得分:5)

让我们来看一个场景。现在这可能是您的情况,也可能不是,但它说明了一点。

假设你的case中的field1和field2是两个整数,method1将它们相加并返回结果。

如果传入对象,那么该方法只能对这两个字段求和。该方法现在也与这些对象强烈耦合。

另一方面,如果仅传入字段,则在这种情况下,两个整数的方法会变得更通用。您现在可以对任意2个任意整数求和,无论它们在哪个对象上。

一般而言,总是将对象暴露给其他方法和类。这促进了松耦合。

例外

AS maaartinus指出如果例如field1和field2是Points并且method1计算了这两个点之间的距离,那么我必须同意传递两个Point会比传递2 xy整数对(4个参数)更好

希望这有帮助

答案 2 :(得分:3)

我会说,这取决于。如果方法对参数进行操作而不是需要整个对象,则该方法可以更清晰且更通用。有时您已准备好参数(例如xy),并且必须先将它们聚合到例如PointImmutablePoint中。一个java.awt.Point,以便能够调用该方法。有时你有一个不同的无关对象(例如,一些{{1}},显然没有扩展{{1}})并且必须提取坐标并创建一个要传递的对象。

通常,如果传递的对象是正确的抽象,那么将它作为一个整体传递就是要走的路。这不是性能问题,而是可读性和可维护性。另请参阅Law of Demeter,这可能会导致对传递的对象更加依赖。

答案 3 :(得分:0)

正如其他人所说,这取决于我的经验,但根据我的经验,传递整个对象会使代码更难阅读和维护。

让我们考虑这个方法 getUserDetails(User user),它依赖于一些方法,例如 getUserAddress(User user) getUserFamilyInfo(User user) 等,这些方法可能会进一步连接到不同的数据源以获取信息。

当整个对象是通过。这使得理解不同服务之间的依赖关系和进行任何重构变得困难。

如果计数小于 3,我更喜欢传递单个参数,或者如果一个不同的大对象需要少量属性,则创建一个 dto。