首选类成员还是在内部方法之间传递参数?


39

假设在一个类的私有部分中有一个供多个私有方法使用的值。人们喜欢将其定义为类的成员变量还是将其作为参数传递给每个方法?为什么?

一方面,我可以看到一个论点,即减少类中的状态(即成员变量)通常是一件好事,尽管如果在类的所有方法中重复使用相同的值,那似乎是一个理想的选择。表示为类状态的候选对象,以使代码看起来更清晰(如果没有其他内容)。

编辑:

为了澄清提出的一些评论/问题,我不是在谈论常量,这与任何特定情况都没有关系,而只是与其他人谈论的一种假设。

暂时忽略OOP角度,以下是我想到的特定用例(假设通过引用传递只是为了使伪代码更整洁)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

所以我的意思是,多个功能之间存在一些共同的变量-在我看来,这是由于较小功能的链接所致。在OOP系统中,如果这些都是类的所有方法(例如,由于通过从大型方法中提取方法进行重构而导致的结果),则该变量可以全部传递给它们,也可以是类成员。


1
该值如何使用?它是恒定的吗?它会改变吗?是否可以在编译之间进行更改?
Oded

当事物被自动确定为相同时,更容易认为这无关紧要。如果您的函数需要像x-1这样的调整后的(x)值,该怎么办?
JeffO 2014年

Answers:


15

如果值是类的属性,则将其保留在类中,否则,将其保留在外部。您不必先设计类方法,而是先设计其属性。如果您不打算首先将该属性放在类中,则可能是有原因的。

就可伸缩性而言,最糟糕的事情就是更改代码以方便使用。很快,您会发现您的代码is肿且重复。但是,我必须承认有时我会违反此规则...便利是如此吸引人。


1
我同意-该类的原始设计/用途应该告诉您它应该是成员变量还是参数。还值得考虑依赖注入角度。
Martijn Verburg

14

如果您实际上不需要在两次调用之间保持状态(显然您不需要,或者您不会问这个问题),那么我宁愿将值作为参数而不是成员变量,因为快速浏览方法的签名告诉您它使用了参数,而立即指出该方法使用了哪些成员变量则比较困难。确定私有成员变量的用途也并不总是那么快。

所以通常我不会同意使用成员变量的代码显然更干净,但是如果方法签名失控,我可能会抛出异常。这是一个值得提出的问题,但无论如何都不是项目所要依靠的。


10

感谢您提出这个问题,我也想问这个问题。

当我考虑这一点时,为什么将其作为论证有一些优势

  • 更容易测试->易于维护(与最后一点有关)
  • 没有副作用
  • 更容易理解

我清楚地看到了您的观点-例如,正在解析Excel文档(例如,使用POI库),而不是将行实例传递给需要使用该行的每个方法,作者具有成员变量currentRow并可以使用它。

我想说这个反模式应该有个名字,对吗?(此处未列出)


您是说哪个反模式?
Vahid Ghadiri '10

简而言之,拥有成员变量只是为了在两个(或多个)函数调用之间共享参数...
Betlista

1

也许您应该提取一个包含所有共享该值的方法的新类。当然,最高级别的方法将在新类中公开。公开该方法进行测试可能会有所帮助。

如果您有两个或多个始终在一起的临时工,那么几乎应该确定要提取一个新类。


1

人们喜欢将其定义为类的成员变量还是将其作为参数传递给每个方法?为什么?

如果我理解您在问什么:类中的方法从定义上讲是实现细节的私有部分,因此,我对直接从任何方法使用任何成员都没有任何疑问。

一方面,我可以看到有一个论点,那就是减少类中的状态(即成员变量)通常是一件好事...

声明a private static final定义常量没有错。编译器将能够在考虑一些优化时使用该值,并且作为常量,它们实际上并未向类添加状态。

尽管如果在整个类的方法中重复使用相同的值...

能够象征性地引用它(例如BLRFL_DURATION),而不必在方法中添加额外的参数,将使您的代码更具可读性,因此更易于维护。


0

如果该值不变,则根据定义它是一个常量,应封装在类中。在这种情况下,不认为会影响对象的状态。我不知道您的情况,但我想到了三角函数中的PI等问题。如果尝试传递此类常量的参数,则如果客户端传递了错误的值或与方法所期望的精度不同的值,则可能使结果暴露于错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.