У меня есть new String(array,"UTF-8")
в одном месте и точно такой же код в другом месте в моем приложении. На самом деле, я могу иметь это во многих местах. И каждый раз я должен использовать эту "UTF-8"
константу для создания String
массива байтов. Было бы очень удобно определить его где-нибудь и использовать повторно, как это делает Apache Commons; увидетьCharEncoding.UTF_8
(Есть много других статических литералов там). Эти ребята подают плохой пример! publicstatic
«свойства» так же плохи, как и служебные классы .
Вот о чем я говорю, а именно:
package org.apache.commons.lang3;
public class CharEncoding {
public static final String UTF_8 = "UTF-8";
// some other methods and properties
}
Теперь, когда мне нужно создать String
из байтового массива, я использую это:
import org.apache.commons.lang3.CharEncoding;
String text = new String(array, CharEncoding.UTF_8);
Допустим, я хочу преобразовать String
в байтовый массив:
import org.apache.commons.lang3.CharEncoding;
byte[] array = text.getBytes(CharEncoding.UTF_8);
Выглядит удобно, верно? Это то, что думают дизайнеры Apache Commons (одна из самых популярных, но просто ужасных библиотек в мире Java). Я призываю вас думать по-другому. Я не могу сказать вам, чтобы вы прекратили использовать Apache Commons, потому что у нас просто нет лучшей альтернативы (пока!). Но в своем собственном коде не используйте публичные статические свойства — никогда. Даже если этот код может показаться вам удобным, это очень плохой дизайн.
Причина, по которой они очень похожи на служебные классы с открытыми статическими методами, — это неразрывные жестко закодированные зависимости. Как только вы используете это CharEncoding.UTF_8
, ваш объект начинает зависеть от этих данных, и его пользователь (пользователь вашего объекта) не может разорвать эту зависимость. Вы можете сказать, что это ваше намерение, в случае "UTF-8"
константы — убедиться, что Юникод используется специально и исключительно. В этом конкретном примере это может быть правдой, но посмотрите на это с более глобальной точки зрения.
Позвольте мне показать вам альтернативу, которую я имею в виду, прежде чем мы продолжим. Вот что я предлагаю вместо этого преобразовать байтовый массив в String
:
String text = new UTF8String(array);
Это псевдокод, так как Java-дизайнеры сделали String
финал класса, и мы не можем его расширить и создать UTF8String
, но вы поняли идею. В реальном мире это будет выглядеть так:
String text = new UTF8String(array).toString();
Как видите, мы инкапсулируем константу «UTF-8» где-то внутри класса UTF8String
, и ее пользователи не имеют представления о том, как именно происходит преобразование «байтового массива в строку».
Внедряя UTF8String
, мы решили проблему дублирования букв UTF-8. Но мы сделали это надлежащим объектно-ориентированным способом — мы инкапсулировали функциональность внутри класса и позволили каждому создавать его объекты и использовать их. Мы решили проблему дублирования функций, а не только дублирования данных.
Размещение данных в одном общем месте ( CharEncoding.UTF_8
) не решает проблему дублирования; на самом деле это еще хуже, в основном потому, что побуждает всех дублировать функциональность, используя один и тот же фрагмент общих данных.
Я хочу сказать, что каждый раз, когда вы видите, что у вас есть некоторое дублирование данных в вашем приложении, начинайте думать о функциональности, которую вы дублируете. Вы легко найдете код, который повторяется снова и снова. Создайте новый класс для этого кода и поместите туда данные как private
свойство (или частное static
свойство). Так вы улучшите свой дизайн и по-настоящему избавитесь от дублирования.