Java 将许多参数传递给方法的最佳实践?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2432443/
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 07:33:47  来源:igfitidea点击:

Best practice for passing many arguments to method?

javaperformanceparametersparameter-passing

提问by Sawyer

Occasionally , we have to write methods that receive many many arguments , for example :

有时,我们必须编写接收许多参数的方法,例如:

public void doSomething(Object objA , Object objectB ,Date date1 ,Date date2 ,String str1 ,String str2 )
{
}

When I encounter this kind of problem , I often encapsulate arguments into a map.

当我遇到这种问题时,我经常将参数封装到一个映射中。

Map<Object,Object> params = new HashMap<Object,Object>();
params.put("objA",ObjA) ;

......

public void doSomething(Map<Object,Object> params)
{
 // extracting params 
 Object objA = (Object)params.get("objA");
 ......
 }

This is not a good practice , encapsulate params into a map is totally a waste of efficiency. The good thing is , the clean signature , easy to add other params with fewest modification . what's the best practice for this kind of problem ?

这不是一个好的做法,将参数封装到映射中完全是在浪费效率。好消息是,干净的签名,只需最少的修改即可轻松添加其他参数。这种问题的最佳实践是什么?

采纳答案by JRL

In Effective Java, Chapter 7 (Methods), Item 40 (Design method signatures carefully), Bloch writes:

Effective Java,第 7 章(方法),第 40 项(仔细设计方法签名)中,Bloch 写道:

There are three techniques for shortening overly long parameter lists:

有三种缩短过长参数列表的技术:

  • break the method into multiple methods, each which require only a subset of the parameters
  • create helper classes to hold group of parameters (typically static member classes)
  • adapt the Builder pattern from object construction to method invocation.
  • 将方法分解为多个方法,每个方法只需要参数的一个子集
  • 创建辅助类来保存一组参数(通常是静态成员类)
  • 将 Builder 模式从对象构造调整到方法调用。

For more details, I encourage you to buy the book, it's really worth it.

更多细节,我鼓励你买这本书,真的很值得。

回答by GaryF

Good practice would be to refactor. What about these objects means that they should be passed in to this method? Should they be encapsulated into a single object?

好的做法是重构。这些对象意味着它们应该传递给这个方法吗?是否应该将它们封装到单个对象中?

回答by Johannes Rudolph

You could create a class to hold that data. Needs to be meaningful enough though, but much better than using a map (OMG).

您可以创建一个类来保存该数据。虽然需要足够有意义,但比使用地图(OMG)要好得多。

回答by tom

Using a map with magical String keys is a bad idea. You lose any compile time checking, and it's really unclear what the required parameters are. You'd need to write very complete documentation to make up for it. Will you remember in a few weeks what those Strings are without looking at the code? What if you made a typo? Use the wrong type? You won't find out until you run the code.

使用带有魔法字符串键的地图是一个坏主意。您失去了任何编译时检查,而且还不清楚所需的参数是什么。您需要编写非常完整的文档来弥补它。几周后,您会在不看代码的情况下记住这些字符串是什么吗?如果你打错了怎么办?使用错误的类型?直到你运行代码你才会发现。

Instead use a model. Make a class which will be a container for all those parameters. That way you keep the type safety of Java. You can also pass that object around to other methods, put it in collections, etc.

而是使用模型。创建一个类,作为所有这些参数的容器。这样你就可以保持 Java 的类型安全。您还可以将该对象传递给其他方法,将其放入集合等。

Of course if the set of parameters isn't used elsewhere or passed around, a dedicated model may be overkill. There's a balance to be struck, so use common sense.

当然,如果这组参数没有在其他地方使用或传递,则专用模型可能会过大。有一个平衡需要达到,所以使用常识。

回答by tom

Using a Map is a simple way to clean the call signature but then you have another problem. You need to look inside the method's body to see what the method expects in that Map, what are the key names or what types the values have.

使用 Map 是一种清理调用签名的简单方法,但是您还有另一个问题。您需要查看方法的主体内部以查看该方法在该 Map 中期望什么,键名称是什么或值具有什么类型。

A cleaner way would be to group all parameters in an object bean but that still does not fix the problem entirely.

一种更简洁的方法是将对象 bean 中的所有参数分组,但这仍然不能完全解决问题。

What you have here is a design issue. With more than 7 parameters to a method you will start to have problems remembering what they represent and what order they have. From here you will get lots of bugs just by calling the method in wrong parameter order.

你在这里遇到的是一个设计问题。如果一个方法有超过 7 个参数,您将开始难以记住它们代表什么以及它们的顺序。从这里开始,仅通过以错误的参数顺序调用方法,您就会得到很多错误。

You need a better design of the app not a best practice to send lots of parameters.

您需要更好的应用程序设计,而不是发送大量参数的最佳实践。

回答by Padmarag

There is a pattern called as Parameter object.

Idea is to use one object in place of all the parameters. Now even if you need to add parameters later, you just need to add it to the object. The method interface remains same.

有一种称为Parameter object的模式。

想法是使用一个对象代替所有参数。现在即使以后需要添加参数,也只需要将其添加到对象中即可。方法接口保持不变。

回答by tvanfosson

First, I'd try to refactor the method. If it's using that many parameters it may be too long any way. Breaking it down would both improve the code and potentially reduce the number of parameters to each method. You might also be able to refactor the entire operation to its own class. Second, I'd look for other instances where I'm using the same (or superset) of the same parameter list. If you have multiple instances, then it likely signals that these properties belong together. In that case, create a class to hold the parameters and use it. Lastly, I'd evaluate whether the number of parameters makes it worth creating a map object to improve code readability. I think this is a personal call -- there is pain each way with this solution and where the trade-off point is may differ. For six parameters I probably wouldn't do it. For 10 I probably would (if none of the other methods worked first).

首先,我会尝试重构该方法。如果它使用那么多参数,它可能太长了。分解它既可以改进代码,又可以减少每个方法的参数数量。您也可以将整个操作重构为它自己的类。其次,我会寻找使用相同参数列表的相同(或超集)的其他实例。如果您有多个实例,则可能表明这些属性属于一起。在这种情况下,创建一个类来保存参数并使用它。最后,我会评估参数的数量是否值得创建地图对象以提高代码可读性。我认为这是个人的决定——这个解决方案的每一种方式都有痛苦,权衡点可能会有所不同。对于六个参数,我可能不会这样做。对于 10,我可能会(如果其他方法都不起作用)。

回答by dimitarvp

It's called "Introduce Parameter Object". If you find yourself passing same parameter list on several places, just create a class which holds them all.

它被称为“引入参数对象”。如果您发现自己在多个地方传递了相同的参数列表,只需创建一个包含它们的类即可。

XXXParameter param = new XXXParameter(objA, objB, date1, date2, str1, str2);
// ...
doSomething(param);

Even if you don't find yourself passing same parameter list so often, that easy refactoring will still improve your code readability, which is alwaysgood. If you look at your code 3 months later, it will be easier to comprehend when you need to fix a bug or add a feature.

即使您没有发现自己经常传递相同的参数列表,这种简单的重构仍然会提高您的代码可读性,这总是好的。如果您在 3 个月后查看您的代码,就会更容易理解何时需要修复错误或添加功能。

It's a general philosophy of course, and since you haven't provided any details, I cannot give you more detailed advice either. :-)

当然,这是一个普遍的哲学,因为你没有提供任何细节,我也不能给你更详细的建议。:-)

回答by Tony

Create a bean class, and set the all parameters (setter method) and pass this bean object to the method.

创建一个 bean 类,并设置所有参数(setter 方法)并将此 bean 对象传递给该方法。

回答by helpermethod

This is often an indication that your class holds more than one responsibility (i.e., your class does TOO much).

这通常表明您的班级承担了多个责任(即,您的班级做得太多)。

See The Single Responsibility Principle

参见单一职责原则

for further details.

了解更多详情。