Public Static Literals ... Are Not a Solution for Data Duplication

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

У меня есть new String(array,"UTF-8") в одном месте и точно такой же код в другом месте в моем приложении. Фактически, я могу использовать его во многих местах. И каждый раз мне приходится использовать эту константу "UTF-8", чтобы создать String из массива байтов. Было бы очень удобно определить ее один раз где-то и повторно использовать, как это делает Apache Commons; см. CharEncoding.UTF_8 (Там есть много других статических литералов). Эти ребята дают плохой пример! public static “свойства” такие же плохие, как утилитарные классы.

Вот о чем я говорю, в частности:

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

Допустим, я хочу преобразовать String в массив байтов:

Кажется удобным, верно? Так считают дизайнеры Apache Commons (одной из самых популярных, но просто ужасных библиотек в мире Java). Я призываю вас думать по-другому. Я не могу сказать вам прекратить использование Apache Commons, потому что у нас просто нет лучшей альтернативы (пока!). Но в своем собственном коде никогда не используйте публичные статические свойства. Даже если этот код может показаться удобным, это очень плохой дизайн.

Причина та же самая, что и у утилитарных классов с публичными статическими методами - они являются неразрывными зависимостями с жестким кодом. Как только вы используете CharEncoding.UTF_8, ваш объект начинает зависеть от этих данных, и его пользователь (пользователь вашего объекта) не может разорвать эту зависимость. Вы можете сказать, что это ваше намерение, в случае с константой "UTF-8" - убедиться, что используется исключительно Юникод. В этом конкретном примере это может быть правдой, но посмотрите на это с более общей точки зрения.

Позвольте мне показать вам альтернативу, которую я имею в виду, прежде чем мы продолжим. Вот что я предлагаю вместо преобразования массива байтов в String:

Это псевдокод, так как разработчики Java сделали класс String конечным, и мы не можем расширить его и создать UTF8String, но вы понимаете идею. В реальном мире это выглядело бы так:

Как видите, мы инкапсулируем константу “UTF-8” где-то внутри класса UTF8String, и его пользователи не знают, как именно происходит преобразование “массива байтов в строку”.

Введя UTF8String, мы решили проблему дублирования литерала “UTF-8”. Но мы сделали это по-настоящему объектно-ориентированным способом - мы инкапсулировали функциональность внутри класса и позволили всем создавать его объекты и использовать их. Мы решили проблему дублирования функциональности, а не просто данных.

Размещение данных в одном общем месте (CharEncoding.UTF_8) на самом деле не решает проблему дублирования, наоборот, это делает ее хуже, в основном потому, что это побуждает всех к дублированию функциональности с использованием того же самого общего куска данных.

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

П.С. Вы можете использовать метод вместо класса, но не статический литерал.

П.П.С. Вы также можете использовать перечисления, но только таким образом.

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-17 at 17:08

sixnines availability badge   GitHub stars