Финальный класс с частным конструктором, каков принцип дизайна

Недавно я проходил один из проектов с открытым исходным кодом Netflix

Там я нашел использование обоих финальных классов вместе с приватным конструктором. Я полностью осознаю, что

  1. финал, чтобы избежать наследования
  2. личное - запретить инстанцирование

Но мне просто интересно узнать, почему они оба используются вместе. Несмотря на то, что методы являются статическими, мы можем использовать их без создания экземпляров, но все же хотим знать принципы разработки.

2 ответа

С этим кодом у вас будут эти функции

  • Не разрешать никому подкласс (extends) твой класс
  • Не разрешать создавать экземпляры вашего класса
  • Создание окончательных переменных или классов повышает производительность (не сильно, но это имеет значение и используется в качестве обычной практики в больших проектах).

В этом случае я не вижу одноэлементный шаблон для получения экземпляра, поэтому в IHMO вы ищете класс помощника / утилиты в API Netflix, где команда разработчиков использовала некоторые стандартные методы, чтобы пользователи использовали свои классы в правильный путь:

StaticFinalClassExample.methodYouWantToCall();

Также, глядя на класс вы связали:

/**
 * This class consists exclusively of static methods that help verify the compliance of OP1A-conformant....
 */

А также:

//to prevent instantiation
private IMFConstraints()
{}

ДОБАВИТЬ:

Если вы хотите получить дополнительную информацию, посмотрите на Item 4 из "Эффективной Java" Джошуа Блоха (2-е издание):

Пункт 4: Обеспечить невозможность использования с помощью частного конструктора

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

  • Их можно использовать для группировки связанных методов по примитивным значениям или массивам, в порядке java.lang.Math или же java.util.Arrays,
  • Их также можно использовать для группировки статических методов, включая фабричные методы (элемент 1), для объектов, реализующих конкретный интерфейс, в виде java.util.Collections,
  • Наконец, они могут быть использованы для группировки методов на final класс, а не расширение класса.

Такие служебные классы не были предназначены для реализации: экземпляр был бы бессмысленным. Однако в отсутствие явных конструкторов компилятор предоставляет открытый конструктор по умолчанию без параметров. Для пользователя этот конструктор неотличим от любого другого. Нередко встречаются непреднамеренно создаваемые классы в опубликованных API.

Попытка реализовать неустранимость путем создания абстрактного класса не работает. Класс можно разделить на подклассы и создать экземпляр класса. Кроме того, это вводит пользователя в заблуждение, что он предназначен для наследования (пункт 17).

Существует, однако, простая идиома, гарантирующая нереализуемость. Конструктор по умолчанию генерируется только в том случае, если класс не содержит явных конструкторов, поэтому класс можно сделать нереализуемым путем включения частного конструктора.

Этот класс состоит из static так называемые "служебные" методы, и поэтому вам не нужен его экземпляр, и, кроме того, НЕПРАВИЛЬНО пытаться получить его экземпляр. Класс является окончательным, так что клиентский разработчик не может выбрать и расширить класс, потому что это противоречит намерениям исходного класса.

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

public static IMFConstraints getInstance()

Другой случай, если никогда не допустимо сделать экземпляр. В этом случае вы предоставляете static методы, которые вызываются самим классом. то есть:

public static void checkIMFCompliance(List<PartitionPack> partitionPacks)

Вы бы назвали приведенный выше метод так:

// your cool client code here...
IMFConstraints.checkIMFCompliance(myPartitionPacks);
// more of your awesome code...

Класс, который вы связали, является последним случаем.

Другие вопросы по тегам