【问题标题】:Java coding style, local variables vs repeated method callsJava 编码风格、局部变量与重复方法调用
【发布时间】:2010-02-09 10:44:05
【问题描述】:

我更喜欢使用局部变量而不是多次调用同一个方法。

/*
 * I prefer this
 */
Vehicle vehicle = person.getVehicle()
if (vehicle instanceof Car) {
   Car car = (Car) vehicle;
   car.openSunroof();
} else if (vehicle instanceof Bike) {
   Bike bike = (Bike) vehicle;
   bike.foldKickstand();
}
/*
 * Rather than this
 */
if (person.getVehicle() instanceof Car) {
   Car car = (Car) person.getVehicle();
   car.openSunroof();
} else if (person.getVehicle() instanceof Bike) {
   Bike bike = (Bike) person.getVehicle();
   bike.foldKickstand();
}
  • 我相信第一种方法的执行速度会快一点
  • 我认为第二种方式违反了 DRY 原则
  • 我发现第一种方式更具可读性且更易于调试(...可以忽略不计,因为我可以跳过)
  • 我不想处理更改对象状态的可能性

你更喜欢哪个,为什么?

【问题讨论】:

    标签: java coding-style


    【解决方案1】:

    出于您提到的所有原因,我更喜欢第一个版本。特别是(只是为了说明你的第四点),这意味着你肯定会得到一致的结果......如果getVehicle() 在第一次调用时返回Car,你可能会在第二个版本中得到非常糟糕的结果,然后在第二个 Bike...

    性能方面并不困扰我(例如,我很乐意反复致电List.size()),但可读性、一致性和非重复性都更为重要。本质上,第一个 sn-p 比第二个更有效地传达了“获取一个值,然后使用它”的理念。

    所以是的,我和你在一起……有人向你推荐第二种形式吗?

    【讨论】:

    • 我相信 Martin Fowler 推荐第二种形式,以使重构更容易。 (在我看来,重构应该让代码更容易理解,而不是更难。)
    • @Jon,你会对 C# 中的属性做同样的事情吗?
    • 我在这个线程上看到了一些 getter 方法调用的支持者 stackoverflow.com/questions/1923795/…
    【解决方案2】:

    是的,第一个肯定更好。我永远不会选择第二种方法。 但是你应该考虑更多地使用多态性。这么重度依赖instanceof不是好的OO设计。

    【讨论】:

    • 很好,这可以使它更干净。但是您可能正在寻找一个通用接口,例如prepareForJourney(),它可以在每个类中单独实现。但是,我们经常使用 3rd 方或遗留类,它们可能不适合轻松应用新接口,但我认为它们可以被包装,并将接口应用到包装器。
    【解决方案3】:

    我通常不喜欢引入额外的变量,因为每增加一点状态都会使方法变得更加复杂。但即使我会说,在您的示例中这是有保证的,因为该变量替换了 4 次相同代码的重复。

    但是变量肯定应该是final

    【讨论】:

      【解决方案4】:

      我同意,但我也尝试在类设计级别减少“instanceof”的使用。

      【讨论】:

        【解决方案5】:

        我个人认为第一个更干净。但是,只要被调用的方法不是计算密集型的,那就没关系了。

        可能第二个更快一些(如果您使用 Java 1.6),因为在第一个示例中您制作了变量的副本,而 java VM 可能会在两个示例中内联函数调用。当然,优化从来都不是这样的调用的论据。编译器做了很多我们不应该打扰的优化(通常它只会降低速度,因为我们不太了解它)。

        【讨论】:

          【解决方案6】:

          作为到目前为止回答这个问题的每个人,我绝对更喜欢第一种风格。它可以更干净:

          Vehicle vehicle = person.getVehicle()
          if (vehicle instanceof Car) {
             ((Car) vehicle).openSunroof();
          } else if (vehicle instanceof Bike) {
             ((Bike) vehicle).foldKickstand();
          }
          

          【讨论】:

            【解决方案7】:

            这两个例子都需要一些工作。尝试将行为推送到 Vehicle 上的抽象(或受保护)方法中。如果这是您无法修改的代码,请使用组合将其放在代码库中的接口内,这样您就不必因您正在使用的库的糟糕设计而污染其余代码。这绝对是一种代码味道。请参阅 Fowler 的重构书中的“Replace Conditional with Polymorphism”。

            【讨论】:

              猜你喜欢
              • 2020-01-25
              • 1970-01-01
              • 1970-01-01
              • 2016-03-21
              • 2019-12-10
              • 1970-01-01
              • 2015-08-19
              • 2018-04-18
              • 1970-01-01
              相关资源
              最近更新 更多