代码改变世界

Effective Java 19 Use interfaces only to define types

2014-03-14 08:06  小郝(Kaibo Hao)  阅读(448)  评论(0编辑  收藏  举报

Reason

The constant interface pattern is a poor use of interfaces.

That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API.

It represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility.

   

// Constant interface antipattern - do not use!

public interface PhysicalConstants {

// Avogadro's number (1/mol)

static final double AVOGADROS_NUMBER = 6.02214199e23;

// Boltzmann constant (J/K)

static final double BOLTZMANN_CONSTANT = 1.3806503e-23;

// Mass of the electron (kg)

static final double ELECTRON_MASS = 9.10938188e-31;

}

   

Solution

If the constants are strongly tied to an existing class or interface, you should add them to the class or interface. For example, all of the boxed numerical primitive classes, such as Integer and Double, export MIN_VALUE and MAX_VALUE constants. If the constants are best viewed as members of an enumerated type, you should export them with an enum type (Item 30). Otherwise, you should export the constants with a noninstantiable utility class (Item 4). Here is a utility class version of the PhysicalConstants example above:

   

// Constant utility class

package com.effectivejava.science;

public class PhysicalConstants {

private PhysicalConstants() { } // Prevents instantiation

public static final double AVOGADROS_NUMBER = 6.02214199e23;

public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;

public static final double ELECTRON_MASS = 9.10938188e-31;

}

   

If you make heavy use of the constants exported by a utility class, you can avoid the need for qualifying the constants with the class name by making use of the static import facility, introduced in release 1.5:

   

// 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

}

   

Summary

Interfaces should be used only to define types. They should not be used to export constants.