第22项:只使用接口来定义类型

ITEM 22: USE INTERFACES ONLY TO DEFINE TYPES
  当一个类实现一个接口时,该接口充当一个类型,可用来引用该类的实例。因此,类实现接口应该说明客户机如何处理类的实例。为任何其他目的定义接口都是不合适的。
  有一种接口没有通过这个测试,那就是所谓的常量接口。该接口不包含任何方法;它仅由静态final字段组成,每个字段导出一个常量。使用这些常量的类实现接口,以避免使用类名限定常量名。举个例子:

// Constant interface antipattern - do not use!
public interface PhysicalConstants {
  // Avogadro's number (1/mol)
  static final double AVOGADROS_NUMBER = 6.022_140_857e23;
  // Boltzmann constant (J/K)
  static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
  // Mass of the electron (kg)
  static final double ELECTRON_MASS = 9.109_383_56e-31; 
}

  常量接口是一种糟糕的对接口的使用方式。类内部使用一些常量是实现细节,常量接口会导致此实现细节泄漏到类导出的API中。类实现常量接口对类的用户没有任何影响。事实上,这甚至可能让他们感到困惑。更糟的是,它表示一种承诺:如果在将来的版本中修改该类,使其不再需要使用常量,那么它仍然必须实现接口,以确保二进制兼容性。如果一个非final类实现了一个常量接口,那么它的所有子类的名称空间都将被接口中的常量污染。
  Java平台库中有几个常量接口,比如Java.io.ObjectStreamConstants。这些界面应该被视为异常,不应该被模仿。
如果您想导出常量,有几个合理的选择。如果常量被强绑定到现有的类或接口,则应该将它们添加到类或接口中。例如,所有装箱的数值基元类(如 Integer 和 Double)都导出MIN_VALUE和MAX_VALUE常量。如果常量被视为枚举类型的成员,则应该使用枚举类型导出它们(item 34)。否则,应该使用一个不可实例化的实用程序类导出常量(item 4)。

// Constant utility class 
package com.effectivejava.science;
public class PhysicalConstants {
  private PhysicalConstants() { } // Prevents instantiation
  public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
  public static final double BOLTZMANN_CONST = 1.380_648_52e-23;
  public static final double ELECTRON_MASS = 9.109_383_56e-31; 
}

  顺便提一下,注意在数字文字中使用下划线 ( _ )。下划线自 Java 7 以来一直是合法的,它对数值文字的值没有影响,但是如果谨慎使用,可以使它们更容易阅读。考虑在数字文字中添加下划线,如果它们包含五个或更多的连续数字,无论浮点数是固定的。对于以10为基数的文字,无论是整数还是浮点数,都应该使用下划线将文字分隔成三组,每组三个数字表示一千的正乘方和负乘方。
  通常,实用程序类要求客户端使用类名限定常量名,例如 PhysicalConstants.AVOGADROS_NUMBER。如果你大量使用一个工具类导出的常量,你可以通过使用静态导入工具来避免使用类名来限定常量:

// Use of static import to avoid qualifying constants
import static com.effectivejava.science.PhysicalConstants.*;
public class Test {
  double atoms(double mols) {
    return AVOGADROS_NUMBER * mols; 
  }
  ...
  // Many more uses of PhysicalConstants justify static import 
}

  总之,接口应该只用于定义类型,它们不应该仅仅用于导出常量。

猜你喜欢

转载自blog.csdn.net/weixin_33860147/article/details/90973300