Главная » Java, Советы » Используйте интерфейсы только для определения типов

0

 

Если класс реализует интерфейс, то этот интерфейс может служить как некий тип, который можно использовать для ссылки на экземпляры этого класса. То, что класс реализует некий интерфейс, должно говорить нечто о том, что именно клиент может делать с экземплярами этого класса. Создавать интерфейс для каких-либо иных целей неправомерно.

Среди интерфейсов, которые не отвечают этому критерию, числится так называемый интерфейс констант (constant interface). Он не имеет методов и содержит исключительно поля static final, передающие константы. Классы, в которых эти константы используются, реализуют данный интерфейс для того, чтобы исключить необходимость в добавлении к названию констант названия класса. Приведем пример:

// Шаблон интерфейса констант – не использоваты!

public interface РhуsiсаlСопstапts

// Число Авогадро (1/моль)

static final double AVOGADROS NUMBER = 6.02214199е23; 85

 

// Постоянная Больцмана (Дж/К)

static final double BOLTZMANN_CONSTANT=1.3806503е-23;

// Масса электрона (кг)

static final double ELECTRON MASS=9.10938188е-31;

 

Шаблон интерфейса констант представляет собой неудачный вариант использования интерфейсов. Появление внутри класса каких-либо констант является деталью реализации. Реализация интерфейса констант приводит к утечке таких деталей во внешний АРI данного класса. То, что класс реализует интерфейс констант, для пользователей класса не представляет никакого интереса. На практике это может даже сбить их с толку. Хуже того, это является неким обязательством: если в будущих версиях класс поменяется так, что ему уже не будет нужды использовать данные константы, он все равно должен будет реализовывать этот интерфейс для обеспечения совместимости на уровне двоичных кодов (binary compatibility). Если же интерфейс констант реализует неокончательный класс; константами из этого интерфейса будет засорено пространство имен всех его подклассов.

В библиотеках для платформы Java есть несколько интерфейсов с константами, например jауа.io.ObjectSt reamConstants. Подобные интерфейсы нужно воспринимать как отклонение от нормы, и подражать им не следует.

Для передачи констант существует несколько разумных способов. Если константы сильно связаны с имеющимся классом или интерфейсом, вы должны добавить их непосредственно в этот класс или интерфейс. Например, все классы-оболочки в библиотеках платформы Java, связанные с числами, такие как Integer и Float, предоставляют константы МIN_VALUE и MAX_VALUE. Если же константы лучше рассматривать как члены перечисления, то передавать их нужно с помощью класса перечисления (статья 21). В остальных случаях вы должны передавать константы с помощью вспомогательнoго класса (utility c!ass), не имеющего экземпляров (статья 3). Представим вариант вспомогательного класса для предыдущего примера PhysicalConstants:

// Вспомогательный класс для констант

public class PhysicalConstants {

private PhysicalConstants() { }

// Предотвращает появление экэемпляра

public static final double AVOGADROS_NUMBER  =6.02214199е23;

public static final doubleBOLTZMANN_CONSTANT  =1.3806503е-23;

 

                 public static final double ELECTRON_MASS  =9.10938188е-31;  

}

 

Хотя представление PhysicalConstants в виде вспомогательного класса требует, чтобы клиенты связывали названия констант с именем класса, это не большая цена за получение осмысленного API. Возможно, что со временем язык Java позволит

 

 

осуществлять импорт статических полей. Пока же вы можете сократить размер программы, поместив часто используемые константы в локальные переменные или закрытые статические поля, например:

 

рrivate static final double РI = Math. PI;

 

Таким образом, интерфейсы нужно использовать только для определения типов. Их не ‘следует применять для передачи констант.

 

Источник: Джошуа Блох, Java TM Эффективное программирование, Издательство «Лори»

По теме:

  • Комментарии