【问题标题】:Java calling methods on instance variable实例变量上的 Java 调用方法
【发布时间】:2012-07-11 11:57:20
【问题描述】:

有两种方法:

 String salary = company.getPerson(id).getData().getSalary();      
 String postcode = company.getPerson(id).getData().getPostCode();

Data data = company.getPerson(id).getData();    
String salary = data.getSalary();     
String postcode = data.getPostCode();

哪种方式是首选方式,为什么? 除了可读性之外还有什么好处?

【问题讨论】:

  • 您可能会发现这是一篇相关文章:en.wikipedia.org/wiki/Law_of_Demeter
  • 您的第一个案例效率较低,因为您调用getPersongetData 两次而不是一次。此外,如果对象发生了变化,两条线换成了不同的人怎么办?

标签: java coding-style


【解决方案1】:

如果此人不存在,我实际上更喜欢第三种选择

Person person = company.getPerson(id);
if(person != null) {
    Data data = person.getData();
    if(data != null) {
        String salary = data.getSalary();
        String postcode = data.getPostCode();
    }
}

这取决于是否可能有空值。如果您可以保证不会有空值,那么您可以消除部分/全部空值检查。

正如另一位用户在下面的评论中指出的那样,可能存在一种情况,即任何方法调用都不能返回 null,在这种情况下,除非性能是一个问题,否则在我看来这真的取决于个人喜好。

即使没有空值检查,我可能仍然希望将它们分成单独的调用。

【讨论】:

  • 你可能是真的,但它不能回答问题。您根据您没有的信息给出第三种解决方案。谁告诉你getPerson 可以返回null?您的帖子回答了更多类似的问题:which is the safer way?
  • @alain.janinm 好吧,我认为我的既安全又清晰。我还在代码下面清楚地说明这取决于值是否能够为空,我没有假设任何事情,但是,我经常发现很多人错过了这种事情,所以总是值得指出的。
  • 您对空值检查是绝对正确的。您的答案中缺少的是没有任何东西可以返回null的情况。那么data var 的创建在您的回答中没有任何理由。
  • 这取决于性能是否是一个很大的问题,如果不是,我仍然更喜欢这个选项,包括Data data = person.getData();。只是个人喜好,我猜在他们都不能返回 null 的情况下。
  • 好的,现在你的答案更完整了;)
【解决方案2】:

如果中间变量有可能为空,那么您应该使用第二个选项以及空检查

Data data = company.getPerson(id).getData();    
if (data != null){
    String salary = data.getSalary();     
    String postcode = data.getPostCode();
    // other code here
}

【讨论】:

    【解决方案3】:

    这取决于您的 getter 方法的复杂性。例如,如果 getPerson(id) 方法很复杂,或/和 getData() 方法很复杂,那么可能会导致性能问题。

    智能编译器可以克服这个问题,但不包括重复的代码部分。但总的来说,从我的角度来看,第二种方式更好。

    【讨论】:

      【解决方案4】:

      没有真正好的风格,这取决于上下文和您的需求。

      使用:

       String salary = company.getPerson(id).getData().getSalary();      
       String postcode = company.getPerson(id).getData().getPostCode();
      

      如果您需要提高内存使用率

      其他用途:

      Data data = company.getPerson(id).getData();    
      String salary = data.getSalary();     
      String postcode = data.getPostCode();
      

      如果您想提高性能

      为了可读性,这对我来说太主观了。老实说,两者都具有可读性。

      第二个示例具有重构company.getPerson(id) 的优点,并且该变量还允许执行一些验证而无需再次调用company.getPerson(id)。我经常喜欢这种风格,但是,如果getPersonne(id)getData() 不能返回null,那么第一个解决方案可能会更好

      【讨论】:

        【解决方案5】:

        出于重构/可读性和性能原因,我个人认为这是最好的解决方案:

        Data data = company.getPerson(id).getData();    
        String salary = data.getSalary();     
        String postcode = data.getPostCode();
        

        【讨论】:

          【解决方案6】:

          您必须考虑性能。虽然“漂亮的代码”很棒,但如果要获得一些昂贵的东西,请保留对它的引用并重用它。

          company.getPerson(id) 很可能涉及用于检索数据的数据库查询,因此虽然第一个选项看起来“更整洁”,但第二个选项可能更好。

          但答案是“视情况而定”——如果每次通话都很便宜,您可以使用第一个选项。

          【讨论】:

            【解决方案7】:

            要考虑的一件事是 getPerson(...) 或 getData() 可能返回 null 的情况。如果其中任何一个返回 null,您将获得 NullPointerException 奖励,因此答案可能取决于其他隐藏因素,而不仅仅是可读性。

            【讨论】:

              【解决方案8】:
               String salary = company.getPerson(id).getData().getSalary();      
               String postcode = company.getPerson(id).getData().getPostCode();
              

              这不太可读,company.getPerson(id).getData() 返回的数据范围仅在运行时,所以它会在那时garbage collected

              Data data = company.getPerson(id).getData();    
              String salary = data.getSalary();     
              String postcode = data.getPostCode();
              

              以上内容更具可读性,但您正在创建一个Data 类型的引用变量,因此garbage collection 收集器将检查堆中“数据”的引用,然后如果发现它符合条件,那么它将收集。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-10-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-02-13
                相关资源
                最近更新 更多