18

我正在处理遗留代码,我经常看到来自同一个对象的多个属性的方法调用被传递到一个方法中:

update(user.getID(), user.getLanguage() etc...)

这样做是否有明显的优势或劣势,或者我是否也可以传入用户对象(在这种情况下)并处理调用方法中的属性?

跟进:

很多优秀的答案,谢谢。为问题中缺乏确切的细节而道歉,但正如我所说,这在我正在处理的整个系统中都可以看到,这似乎是一个很好的简单示例。请随意将这个问题变成一个社区 wiki 问题,因为没有一个答案可以被其他人接受,因为它们都很好并且有有效的观点。

4

9 回答 9

16

两者都有自己的优势。我会根据它应该做什么来决定每种方法。但是,对于遗留代码,除非确实存在问题,否则我宁愿不更改任何内容。

pro几个值,con对象引用:

  • 你没有绑定到特定的类,你可以从其他来源传递值
  • 方法不能(出乎意料地)改变对象状态(C++ 可以为此使用“const”)

Pro 传递单个用户对象:

  • 您被绑定到用户对象,因此很难意外传递不相关/无效的值
  • 很明显,该方法需要用户对象的数据
  • 更改(例如重命名)getter 需要在方法的所有调用中进行更改,而不仅仅是在其实现中
  • 如果添加了新属性并且需要传递,则类似
  • 方法可以改变对象状态

如您所见,根据您的需要,可以将房产视为优势或劣势。

于 2012-05-16T10:10:13.247 回答
14

事实上,传递对对象的引用会好得多,原因有二:

  • 它避免在调用该方法的每个地方重复所有 getter(DRY 原则)
  • 它导致更短的方法签名。方法几乎不应该有超过三个参数,因为它很容易混淆顺序,并且很难重构。

为避免参数列表过长,建议的重构是创建一个包含所有数据的对象——你不是很幸运,你已经有了这样一个对象吗?

于 2012-05-16T09:46:39.053 回答
6

这取决于您是否会接受调用方法对对象类的依赖。

当使用这个

update(user)

声明更新的类必须知道用户的类。

如果你使用这个

update(user.getID(), user.getLanguage() etc...)

并且成员是原语或属于 Java 标准库,而不是 update() 对用户类没有进一步的依赖关系......

于 2012-05-16T09:53:38.750 回答
5

这是一种代码异味,让我考虑将 update() 方法移至用户类。面向对象设计的一大原则是封装——将您的数据和对这些数据的操作捆绑在一起。

然后你就有了告诉,不要问的原则。告诉一个对象做某事比向它询问信息要好。

程序代码获取信息然后做出决定。面向对象的代码告诉对象做事。

当然我没有足够的细节说你绝对应该做这样的事情,但这是需要考虑的事情。

于 2012-05-16T14:00:40.967 回答
3
  1. 看起来很奇怪
  2. 这意味着方法签名看起来像update(String, String, String...)这样引入了以错误顺序传递参数的风险
  3. 如果您需要在某个阶段在更新方法中考虑新属性,则无需更改方法的签名,只需更改其实现即可。
  4. 我不知道有什么update作用,但将其作为用户类的一部分可能是有意义的:user.update(additionalInformation).
于 2012-05-16T09:46:27.913 回答
3

根据我的经验,我认为这取决于方法应该做什么,如果它严格链接到包含所有参数的对象,最好传递对象,例如在执行更新或保存的 DAO 对象中最好传递Domain对象,否则如果方法更通用,并且有可能所有参数不是来自同一个对象,最好将参数传递给方法。

于 2012-05-16T09:47:31.340 回答
2

考虑到您正在处理遗留代码,您需要确保更改方法

签名不会破坏任何可能调用它的代码。如果您可以完全控制调用这些方法的代码库,那么您可以通过传入user对象来简化代码。

您还应该考虑用户对象是否是“重量级”对象,每次调用这些方法时都会加载可能浪费创建的附加数据。user这将是您不能将对象作为参数传递的原因之一。同样的道理也适用于延迟加载的对象。

不传递整个对象的另一个可能原因可能是您不希望它被该方法更新,并且由于“某种原因”不能使其成为不可变的。可以使用户对象的 getter 方法返回值的“安全防御副本”。有关这种在多线程应用程序中特别有用的编码实践,请参阅 Joshua Bloch 的有效 java。

于 2012-05-16T09:53:30.027 回答
2

很难说从代码片段中更新的方法是什么。但是如果你传入用户对象,你将把用户对象耦合到方法中。如果您只是传入字符串、整数等,则可以将该方法与用户以外的源一起使用。我的建议是,你不应该强迫方法比它需要的更具体。

于 2012-05-16T09:46:19.790 回答
2

将一个对象的属性作为单独的参数传递给方法没有任何好处。它的缺点是代码变得难以阅读和维护。争论越少越好。如果您可以将参数组合在一个对象中,那就去做吧。

如果您想重构它,有一种重构技术,称为Preserve Whole Object。您可能还会发现我对类似主题的回答很有用。

于 2012-05-16T10:07:51.453 回答