【问题标题】:Programming techniques: Passing objects or values as method parameter编程技巧:将对象或值作为方法参数传递
【发布时间】:2010-11-11 02:40:31
【问题描述】:

传参在日常编程中很常见,但是我们应该将参数作为对象还是值来传递呢?

(A)

public boolean isGreaterThanZero(Payment object) {
    if (object.getAmount() > 0) {
       return true;
    }

    return false;
}

(B)

public boolean isGreaterThanZero(int amount) {
    if (amount > 0) {
       return true;
    }

    return false;
}

【问题讨论】:

    标签: java oop parameter-passing


    【解决方案1】:

    两者都不是。

    使用适当的 OOP,您将在 Payment 对象上使用 isGreaterThanZero(),即:

    class Payment {
      int amount
      public boolean isGreaterThanZero() {
        return amount > 0
      }
    }
    

    然后:

    Payment payment
    boolean flag = payment.isGreaterThanZero()
    

    【讨论】:

    • 嗨,假设这是一个检查银行账户是否有足够的提款金额的业务逻辑。我不同意在系统的模型层写业务逻辑。
    • 如果它严格地与一个域对象一起工作并且不受其他任何东西的影响,它就属于该域对象。你还会把那个方法放在哪里。在服务中没有意义,因为它不限于服务。在 Utilities 类中是不对的,因为静态 Utilities 不是好的 OOP。 (有时是必要的,是的,但不是一个理想的选择。)在此示例中,该方法被赋予一个对象,并通过调用该对象上的方法返回答案。没有使用其他任何东西......所以它属于对象。
    • 但是这个方法看起来像一个通用的方法。我们可以在 Util 类中有一个静态方法来进行泛型比较。您对此有何看法?
    【解决方案2】:

    假设您询问的是参数传递,而不是对象设计...

    在设计方法时需要考虑多个方面。

    1. 这个方法可以在其他地方使用吗?在您的示例中,答案可能是肯定的 - 它可以判断任何 int 是否大于零 - 在这种情况下 (B) 更有用。
    2. 如果方法需要多个参数并且特定于代码中的某个对象,则传递该对象。

    在有意义的地方,尽量减少代码中模块之间的依赖关系。在您的示例中, (A) 引入了对 Payment 对象的不必要依赖。但是,如果该方法需要 Payment 对象的几个成员变量(因为它是特定于支付的),那么请务必将 Payment 对象作为参数传递。

    【讨论】:

      【解决方案3】:

      这是一个人为的例子,但如果这是接收类与支付的唯一交互,我会使用该值来解耦。没有必要创建多余的类依赖项。

      编辑:Marcel 和我同时输入相同的内容。 :) 这个。

      【讨论】:

        【解决方案4】:

        这个问题的答案将针对特定情况,因此无法给出明确的答案,但何时使用哪种方法的问题仍然有效。

        我会在以下情况下传递一个对象:

        1. 该方法需要处理大量从外部传入的数据。最好将这些参数包装在一个对象中,因为这样做意味着您可以让该方法采用一个参数,而不是每个数据值 1 个。您还可以将参数验证逻辑重构到包装类中以获得更好的局部性。1。
        2. 当在整个 API 中频繁使用相同的参数组合时

        当参数很少的时候我会传一个值,而且都是简单的值类型。

        【讨论】:

        • 嗨,你能详细说明一下吗?如果要传递给方法的参数太多,我想将它们封装在一个对象和进程中会更好。
        • @lianteh 当然。你有什么具体的部分想让我详细说明吗?
        • +1 用于封装“太多参数”。绝对是代码气味。
        • 我同意 Crippledsmurf 的观点,在理想情况下您将拥有所有原始类型(或者更好的是,根本没有参数),但有时它只是没有意义 - 没关系,只是确保方法和对象之间的“耦合”是合乎逻辑的。
        【解决方案5】:

        根据 OOP 概念,我们应该使用Objects。但是,不要过度使用它。例如,在您的示例中,我会使用int。但是在我在很多地方使用多个值的方法中,我会使用一个对象。
        我不会只使用一个数据成员“amount”来创建Payment 类。

        【讨论】:

        • 嗨,这只是我的问题的一个简单示例。 =)
        【解决方案6】:

        我的目标是保持事物解耦。如果 isGreaterThanZero() 真正需要的只是金额,那么 int 版本会更好,因为它不会将实现耦合到 Payment 类。

        【讨论】:

          【解决方案7】:

          我认为我们应该尽可能使用原始类型(int、double、boolean、char)作为参数,因为存在原始类型并非偶然。我更喜欢第二种选择,因为它更通用(它不会强迫您提供 Payment 对象,任何 int 值都会很好)。但是当你需要对象的状态(对象数据的至少两个值)时,情况可能会发生变化,你可以使用值作为参数以获得更通用的使用可能性,也可以使用对象作为参数来简化。

          【讨论】:

            【解决方案8】:

            是的,我们可以在Java程序中将对象作为参数传递。

            第一种方式

                 class demo
                 {private int length=1;
                  private int breadth=1;
                  private int area;
                  void input(int length,int breadth)
                  {
                     this.length=length;
                     this.breadth=breadth;
                  }
                  void add(demo d1,demo d2)
                  {
                      length=d1.length+d2.length;
                     breadth=d1.breadth+d2.breadth;
                  }
                 void output()
                 {
                     System.out.println("\nLength="+length+"\nBreadth="+breadth);
                 }
            
                    public static  void main(String args[])
                    {
            
                        demo d1=new demo();
                        demo d2=new demo();
                        d1.input(1, 1);
                        d1.output();
                        d2.input(2, 2);
                        d2.output();
                        demo d3=new demo();
                        d3.add(d1, d2);
                        d3.output();
            
                    }
            
                 }
            

            第二种方式

            class demo {private int length; private int breadth; void input(int length,int breadth) { this.length=length; this.breadth=breadth; } demo add(demo d2) { demo obj=new demo();//Neccesary as we want to return complete object irrespective of its number of data fields obj.length=length+d2.length;//Storing the length of two objects in the obj obj.breadth=breadth+d2.breadth; return obj; } void output() { System.out.println("\nLength="+length+"\nBreadth="+breadth); } public static void main(String args[]) { demo d1=new demo(); demo d2=new demo(); d1.input(1, 1); d2.input(2, 2); demo d3=d1.add(d2);//Here we created new object d3 called add() by d1 and passed d2 object through it d3.output(); } }

            【讨论】:

              【解决方案9】:

              有时,将对象地址(或指针、句柄,无论您如何称呼它)作为参数传递,然后将其转换为方法(作为所需对象的实例)比将对象作为参数传递更快。它只是一种限制编译方式的方法。如果有时它没有改变任何东西,在其他情况下传递地址将使程序更快。这是一个低级编译器的东西,但它确实可以使代码更快。

              【讨论】:

              • 你说的是什么语言?在 Java 中,对象的引用总是被传入,而不是对象本身。您是在谈论传递对象副本而不是引用的语言吗?有这样的语言吗? (这不是“按值语义复制”吗,这是这个问题首先要问的?
              【解决方案10】:

              我之前的答案的附录。它还取决于编译器优化和方法调用上下文。如果对象在调用方法之前已经定义,或者如果它是一个可以从内联和优化中受益的方法,那么使用地址不是一个好主意。 如果您处于循环中,那么使用地址是个好主意。 您必须考虑一下该方法将如何在特定程序中使用(= 预计它将如何编译)。

              【讨论】:

                猜你喜欢
                • 2020-06-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-22
                • 2013-05-14
                • 2021-07-29
                • 2018-09-26
                • 1970-01-01
                相关资源
                最近更新 更多