Недостатки для определения нестатического регистратора

Комментарии для этого ответа Как вы сокращаете шаблонный код календаря Java? настоятельно рекомендуем не использовать регистраторы как переменные-члены экземпляра. Я могу думать о двух отрицательных побочных эффектах:
1) журналы суперкласса с регистратором подкласса
2) объект не может быть сериализован (если не отмечен переходный процесс)

Но если сериализация не требуется, и регистрация с именем подкласса не является проблемой, есть ли что-то еще, почему этого следует избегать? Я думаю, что это уменьшает код шаблона и позволяет избежать ошибок копирования-вставки при копировании определения переменной регистратора из одного класса в другой. Даже Spring framework (который, как я считаю, имеет очень хорошие стандарты кодирования) использует этот метод.

Ответ 1

Если ваш Logger является членом экземпляра, а не статическим, Logger должен быть восстановлен каждый раз, когда создается новый объект. Хотя эти накладные расходы, вероятно, несущественны, но это один из недостатков.

С точки зрения дизайна, Loggers на самом деле не являются свойством объекта, поскольку они обычно являются метаинформацией о вашей системе, а не деловой информацией в самой системе. A Logger не является частью чего-то вроде объекта Car таким же образом, как и Engine или Transmission. Связывание регистраторов с объектами как членами (в большинстве случаев) не имеет смысла семантически больше всего.

Ответ 3

Основным отличием от регистрации суперкласса с именем подкласса, конечно же, является то, что у вас будет один объект Logger для каждого члена вашего класса. В зависимости от того, сколько классов использует ведение журнала, это может быть огромное количество регистраторов, поэтому проблема с памятью может быть проблемой.

Плюс от абстрактной точки зрения, регистратор действительно принадлежит классу и может делиться между всеми экземплярами, а не каждому экземпляру, нуждающемуся в его собственной частной копии, поэтому имеет смысл объявить его статичным. Перевернув вопрос, какие преимущества он должен сделать нестационарным? (Возможность передать getClass() в вызов getLogger() вместо передачи в константе класса - это единственное, что я могу придумать, и что такая крошечная вещь).

Ответ 4

Другая, возможно, небольшая потеря: вложенная память, особенно когда у вас много экземпляров, каждый со своим собственным журналом

Ответ 5

Попробуйте отладить ошибку, когда вы видите сообщение, сгенерированное классом SuperClass, когда ошибка действительно регистрируется в классе SubClass. Я видел несколько ситуаций, когда разработчики создают класс LoggingUtils, который генерирует сообщения, которые обычно дублируют вещи, которые уже запекаются в рамках ведения журнала.

Единственная реальная ситуация, которую я вижу для использования общего экземпляра журнала, - это что-то вроде Apache commons HttpClient logger httpclient.wire, который делится между несколькими классами для регистрации содержимого запросов и ответов, отправленных клиентом. Эта конкретная ситуация с регистрацией не регистрирует информацию для фактической реализации пакета, она регистрирует информацию о всей http-транзакции.

Ответ 6

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

Также, как говорит apache, это сохраняет ссылки, поэтому они не будут освобождены после использования.

Apache Wiki говорит так:

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

Технический результат использования static очевиден: для всех экземпляров класса существует только одна ссылка на журнал. Это, безусловно, эффективность памяти; требуется только одна ссылка (4 или 8 байт) независимо от того, сколько экземпляров создано. Он также эффективен с точки зрения ЦП; поиск, необходимый для поиска экземпляра журнала, выполняется только один раз, когда класс сначала ссылается.