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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21136227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:50:37  来源:igfitidea点击:

Passing whole object vs passing object's property

javaperformanceoop

提问by Lucas

I'm thinking about the solution for my application. Here's the situation: I have a class with a method that takes ObjectA as an input parameter and calls several small methods, each one of these methods needs some parts of the ObjectA (they don't overlap, i.e. method1()needs ObjectA.field1and ObjectA.field2, method2()needs ObjectA.field3and so on...) Now the question is: given the general good code practices and performance is it better to pass ObjectA to each one of these methods so they can extract the value they need on their own or is it better just pass them values? I mean:

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

method1(ObjectA);
method2(ObjectA);

or

或者

method1(Object1.getField1(), ObjectA.getField2());
method2(ObjectA.getField3());

Thanks for any answers!

感谢您提供任何答案!

采纳答案by christopher

Keep in mind, with your code, you're not actually passing ObjectA. Namely, you're passing the reference type to ObjectA, so on a performance note the difference between passing a Stringobject reference and a ObjectAobject reference would be negligible.

请记住,使用您的代码,您实际上并没有通过ObjectA. 也就是说,您将引用类型传递给ObjectA,因此在性能说明上,传递String对象引用和ObjectA对象引用之间的差异可以忽略不计。

The way I would write it

我会写它的方式

I would pass the whole object, if the method is pertinent to the class. My reasoning for this is to split up class knowledge as much as possible. What I mean by this is the following.

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

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

My first criticism here is that this method assumes that the input is the correct field. My second, is that now, the class calling this code needs to know a little bit more about this method, because it has to call it like this:

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

doSomethingRelatedToTheClass(myObject.getValue());

And what this means is, if you find that another member of ObjectAworks better inside this method, or you want to access other members of ObjectA, and you change doSomething()to reflect this change, you also need to change the method call, to:

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

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

So by passing in the whole object, you abstract that detail away, and the method can handle it; namely:

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

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();
}

When a change to one class, results in a change in other classes, this is an Anti-pattern called Shotgun Surgery.

当对一个类的更改导致其他类的更改时,这是一种称为Shotgun Surgery的反模式。

Edit

编辑

I've had chance to review my answer here and I've amended my original answer slightly because I believe it isn't the best solution for allsituations. As above, if a method is related to a class specifically, then the instantiation of that class (or more preferably, its superclass or implemented interface[s]) should be the parameter.

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

The time this is not the case is when the functionality can be generic. An example of a generic function might be:

不是这种情况的时候是功能可以是通用的。通用函数的一个例子可能是:

public String[] findNouns(String sentence);

In this case, finding the nouns in a sentence might be appropriate for lots of use cases, and not just the use cases that you have defined. As such, passing in the value is the only sensible approach because otherwise, you couple two pieces of logic together that have no direct relationship. The finding of nouns and the arbitrary object you have defined.

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

In Summary

总之

  • If the method is logic that is related to the object, pass in the object

  • If the method has nothing to do with the object, and the object is just using it as a utility function, then pass in the value and name the function generically.

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

  • 如果方法与对象无关,而对象只是将其用作实用程序函数,则传入值并通用命名函数。

回答by maaartinus

I'd say, it depends. A method may be clearer and more general if it operates on the arguments rather than requiring a whole object. Sometimes you have the arguments ready (e.g., xand y) and would have to aggregate them first into e.g. a Pointin order to be able to call the method. Sometimes you have a different unrelated object (e.g., some ImmutablePoint, obviously not extending java.awt.Point) and would have to extract the coordinates and create an object to pass.

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

Usually, if the passed object is the proper abstraction, then passing it as a whole is the way to go. It's not a performance question, it's about readability and maintainability. See also the Law of Demeterwhich may lead to looser dependency on the passed object.

通常,如果传递的对象是正确的抽象,那么将其作为一个整体传递是可行的方法。这不是性能问题,而是关于可读性和可维护性。另请参阅德米特法则,这可能会导致对传递对象的依赖性降低。

回答by n4rzul

Let's examine a scenario. Now this may or may not be your scenario but it illustrates a point.

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

Lets say field1 and field2 in your case are two integers and method1 sums them and returns the result.

假设您的情况下的 field1 和 field2 是两个整数,method1 将它们相加并返回结果。

If you pass in the objects then that method can only ever sum those two fields. The method is also now strongly coupled with those objects.

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

On the other hand, if you pass in only the fields, the two integers in this case your method becomes more generic. You can now sum any 2 arbitrary integers regardless of which objects they are on.

另一方面,如果您只传入字段,则在这种情况下,您的方法的两个整数将变得更加通用。您现在可以对任意 2 个任意整数求和,而不管它们位于哪个对象上。

In general though, always expose as little of your objects to other methods and classes. This promotes loose coupling.

但总的来说,始终将尽可能少的对象暴露给其他方法和类。这促进了松散耦合。

Exceptions

例外

AS maaartinus points out if for example field1 and field2 were Points and method1 calculated the distance between those two points, then I would have to agree that passing two Points would be better than passing 2 xy integer pairs (4 parameters)

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

Hope this helps

希望这可以帮助