Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Effective Java TM.doc
Скачиваний:
3
Добавлен:
28.09.2019
Размер:
2.11 Mб
Скачать

Используйте интерфейсы только для определения типов

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

Среди интерфейсов, которые не отвечают этому критерию, числится так назы­ваемый интерфейс констант (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 позволит

86

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]