【问题标题】:When to use an object instance variable versus passing an argument to the method何时使用对象实例变量与将参数传递给方法
【发布时间】:2010-09-25 15:51:10
【问题描述】:

您如何决定将参数传递给方法还是简单地将它们声明为对所有对象方法可见的对象实例变量?

我更喜欢将实例变量保存在类末尾的列表中,但是随着程序的增长,这个列表会变得更长。我想如果一个变量被传递得足够频繁,它应该对所有需要它的方法都是可见的,但是我想知道,“如果一切都是公开的,那么根本不需要传递任何东西!”

【问题讨论】:

  • 如果你有具体的例子,你可能会得到更直接有用的答案

标签: variables methods parameter-passing declaration


【解决方案1】:

由于您指的是实例变量,我假设您使用的是面向对象的语言。在某种程度上,何时使用实例变量、如何定义它们的范围以及何时使用局部变量是主观的,但无论何时创建类,您都可以遵循一些经验法则。

  • 实例变量通常被认为是类的属性。将它们视为将从您的类中创建的对象的形容词。如果您的实例数据可用于帮助描述对象,那么可以肯定的是,它是实例数据的不错选择。

  • 在方法范围内使用局部变量来帮助它们完成工作。通常,方法应该具有获取一些数据、返回一些数据和/或处理的目的/对一些数据运行算法。有时,将局部变量视为帮助方法从头到尾的方式会有所帮助。

  • 实例变量范围不仅是为了安全,也是为了封装。不要假设“目标应该是让所有变量保持私有”。在继承的情况下,将变量设置为受保护通常是一个不错的选择。您无需将所有实例数据标记为公开,而是为需要访问外部世界的对象创建 getter/setter。不要让它们全部可用 - 只有你需要的那些。这将贯穿整个开发生命周期 - 从一开始就很难猜测。

当谈到在类中传递数据时,如果没有看到一些代码,就很难说你正在做的事情是好的做法。有时,直接对实例数据进行操作就可以了;其他时候,不是。在我看来,这是随着经验而来的——随着你的面向对象思维能力的提高,你会发展出一些直觉。

【讨论】:

  • 我的答案是将此答案添加到 H-Man2 答案(终生)。当且仅当它是对象的持久状态时,它才应该是成员属性。也就是说,该值本身在当前方法堆栈范围之外是有意义的。
  • 我的直觉反应是同意 David 和 H-MAn2。但是,我正在阅读 Robert c Martin 的“干净代码”,在第 3 章中,他重构代码以将某些内容从方法参数移动到成员变量,因为有很多参数是不好的。总的来说,我猜如果你的类只有一个职责,那么对象的生命周期与计算的生命周期相同,所以实际的答案可能是如果你不得不问这个问题,那么你的类就太大了?
  • @DavidRodríguez-dribeas 方法堆栈是什么意思?
  • @committedandroider: 如果值超过当前函数调用
【解决方案2】:

这主要取决于您存储在变量中的数据的生命周期。如果数据仅在计算期间使用,则将其作为参数传递。 如果数据绑定到对象的生命周期,则使用实例变量。

当您的变量列表变得太长时,考虑将类的某些部分重构为一个新类也许是一个好点。

【讨论】:

    【解决方案3】:

    在我看来,实例变量只有在跨调用使用数据时才是必需的。

    这是一个例子:

    myCircle = myDrawing.drawCircle(center, radius);
    

    现在让 myDrawing 类使用 15 个辅助函数来创建 myCircle 对象,每个函数都需要中心和半径。它们仍然不应设置为 myDrawing 类的实例变量。因为他们再也不会被需要了。

    另一方面,myCircle 类需要将中心和半径都存储为实例变量。

    myCircle.move(newCenter);
    myCircle.resize(newRadius);
    

    为了让 myCircle 对象在进行这些新调用时知道它的半径和中心是什么,需要将它们存储为实例变量,而不仅仅是传递给需要它们的函数。

    所以基本上,实例变量是一种保存对象“状态”的方法。如果变量不需要知道对象的状态,那么它不应该是实例变量。

    至于公开一切。它可能会让你的生活更轻松。但它会回来困扰你。豌豆不要。

    【讨论】:

    • 你可以定义 move 来使用参数 (oldCenter, newCenter)。
    【解决方案4】:

    恕我直言:

    如果变量构成实例状态的一部分,那么它应该是一个实例变量——classinstance HAS-A instancevariable。

    如果我发现自己反复将某些东西传递给实例的方法,或者我发现我有大量实例变量,我可能会尝试查看我的设计,以防我遗漏了某些东西或在某处做了错误的抽象.

    希望对你有帮助

    【讨论】:

      【解决方案5】:

      当然,在类中保留一个大的公共变量列表很容易。但即使凭直觉,你也可以看出这不是要走的路。

      在您将要使用它之前定义每个变量。如果变量支持特定方法的功能,请仅在方法范围内使用。

      还要考虑安全性,公共类变量容易受到来自“外部”代码的不必要更改的影响。您的主要目标应该是保持所有变量私有,而任何不是私有的变量都应该有充分的理由这样做。

      关于在堆栈中一直传递参数,这会很快变得丑陋。一个经验法则是保持你的方法签名干净和优雅。如果您看到许多方法使用相同的数据,请确定它是否足够重要以成为类成员,如果不是,请重构您的代码以使其更有意义。

      归结为常识。仔细想想你声明每个新变量的位置和原因,它的功能应该是什么,并从那里决定它应该存在于哪个范围内。

      【讨论】:

      • 您通常希望方法是公开的,以便您可以对它们进行单元测试。
      猜你喜欢
      • 2012-07-12
      • 2011-10-09
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      相关资源
      最近更新 更多