Skip to content

[J]ava and [C]sharp

Serhii Chepets edited this page Apr 12, 2023 · 6 revisions

“If garbage collection really worked, most programs would delete themselves the first time they were run.”

― Robert Sewell


[J01]: Avoid Long Import Lists by Using Wildcards

If you use two or more classes from a package, then import the whole package with

import package.*;

Long lists of imports are daunting to the reader. We don’t want to clutter up the tops of our modules with 80 lines of imports. Rather we want the imports to be a concise statement about which packages we collaborate with.

Specific imports are hard dependencies, whereas wildcard imports are not. If you specifically import a class, then that class must exist. But if you import a package with a wildcard, no particular classes need to exist. The import statement simply adds the package to the search path when hunting for names. So no true dependency is created by such imports, and they therefore serve to keep our modules less coupled.

There are times when the long list of specific imports can be useful. For example, if you are dealing with legacy code and you want to find out what classes you need to build mocks and stubs for, you can walk down the list of specific imports to find out the true qualified names of all those classes and then put the appropriate stubs in place. However, this use for specific imports is very rare. Furthermore, most modern IDEs will allow you to convert the wildcarded imports to a list of specific imports with a single command. So even in the legacy case it’s better to import wildcards.

Wildcard imports can sometimes cause name conflicts and ambiguities. Two classes with the same name, but in different packages, will need to be specifically imported, or at least specifically qualified when used. This can be a nuisance but is rare enough that using wildcard imports is still generally better than specific imports.


[J01]: Используйте обобщенные директивы импорта

Если вы используете два и более класса из пакета, импортируйте весь пакет командой

import package.*;

Длинные списки импорта пугают читателя кода. Начало модуля не должно загромождаться 80-строчным списком директив импорта. Список импорта должен быть точной и лаконичной конструкцией, показывающей, с какими пакетами мы собираемся работать.

Конкретные директивы импорта определяют жесткие зависимости, обобщенные директивы импорта — нет. Если вы импортируете конкретный класс, то этот класс обязательно должен существовать. Но пакет, импортируемый обобщенной директивой, может не содержать ни одного класса. Директива импорта просто добавляет пакет в путь поиска имен. Таким образом, обобщенные директивы импорта не создают реальных зависимостей, а следовательно, способствуют смягчению логических привязок между модулями.

В некоторых ситуациях длинные списки конкретных директив импорта бывают полезными. Например, если вы работаете с унаследованным кодом и хотите узнать, для каких классов необходимо создать заглушки и имитации, можно пройтись по конкретным спискам импорта, узнать полные имена классов и написать для них cоответствующие заглушки. Однако такое использование конкретных директив импорта встречается крайне редко. Более того, многие современные IDE позволяют преобразовать обобщенный список импорта в список конкретных директив одной командой. Таким образом, даже в унаследованном коде лучше применять обобщенный импорт.

Обобщенные директивы импорта иногда становятся причиной конфликтов имен и неоднозначностей. Два класса с одинаковыми именами, находящиеся в разных пакетах, должны импортироваться конкретными директивами (или по крайней мере их имена должны уточняться при использовании). Это создает определенные неудобства, однако ситуация встречается достаточно редко, так что в общем случае обобщенные директивы импорта все равно лучше конкретных.


[J01]: Використовуйте узагальнені директиви імпорту

Якщо ви використовуєте два та більше класи з пакета, імпортуйте весь пакет командою

import package.*;

Довгі списки імпорту лякають читача коду. Початок модуля не повинен захаращуватися 80-рядковим списком директив імпорту. Список імпорту має бути точною та лаконічною конструкцією, яка показує, з якими пакетами ми збираємося працювати.

Конкретні директиви імпорту визначають жорсткі залежності, узагальнені директиви імпорту – ні. Якщо ви імпортуєте конкретний клас, цей клас обов'язково повинен існувати. Але пакет, що імпортується узагальненою директивою, може не містити жодного класу. Директива імпорту просто додає пакет до пошуку імен. Отже, узагальнені директиви імпорту створюють реальних залежностей, отже, сприяють пом'якшенню логічних прив'язок між модулями.

У деяких ситуаціях довгі списки конкретних директив імпорту є корисними. Наприклад, якщо ви працюєте з успадкованим кодом і хочете дізнатися, для яких класів необхідно створити заглушки та імітації, можна пройтися за конкретними списками імпорту, дізнатися повні імена класів та написати для них відповідні заглушки. Однак таке використання конкретних директив імпорту трапляється вкрай рідко. Більше того, багато сучасних IDE дозволяють перетворити узагальнений список імпорту на список конкретних директив однією командою. Таким чином, навіть у успадкованому коді краще застосовувати узагальнений імпорт.

Узагальнені директиви імпорту іноді стають причиною конфліктів імен та неоднозначностей. Два класи з однаковими іменами, що знаходяться в різних пакетах, повинні імпортуватись конкретними директивами (або принаймні їхні імена повинні бути уточнені під час використання). Це створює певні незручності, проте ситуація зустрічається досить рідко, так що в загальному випадку узагальнені директиви імпорту все одно кращі за конкретні.


[J02]: Don’t Inherit Constants

I have seen this several times and it always makes me grimace. A programmer puts some constants in an interface and then gains access to those constants by inheriting that interface. Take a look at the following code:

Example: C# | Java


[J02]: Не наследуйте от констант

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

Приклад: C# | Java


[J02]: Не успадковуйте від констант

Я вже неодноразово зустрічався з цим явищем, і щоразу воно змушувало мене невдоволено скривитися. Програміст розміщує константи в інтерфейсі, а потім успадковує від цього інтерфейсу для отримання доступу до константів. Погляньте на наступний код:

Пример: C# | Java


[J03]: Constants versus Enums

Now that enums have been added to the language, use them! Don’t keep using the old trick of public static final ints. The meaning of ints can get lost. The meaning of enums cannot, because they belong to an enumeration that is named.

What’s more, study the syntax for enums carefully. They can have methods and fields. This makes them very powerful tools that allow much more expression and flexibility than ints. Consider this variation on the payroll code:

Example: C# | Java


[J03]: Константы против перечислений

В языке появились перечисления — пользуйтесь ими! Не используйте старый трюк с public static final int. Смысл int может потеряться; смысл перечислений потеряться не может, потому что они принадлежат указанному перечислению.

Тщательно изучите синтаксис перечислений. Не забудьте, что перечисления могут содержать методы и поля. Это очень мощные синтаксические инструменты, значительно превосходящие int по гибкости и выразительности. Рассмотрим следующую разновидность кода начисления зарплаты:

Пример: C# | Java


[J03]: Константи проти перерахувань

У мові з'явилися перерахування - користуйтеся ними! Не використовуйте старий трюк із public static final int. Сенс int може загубитися; сенс перерахувань загубитися неспроможна, оскільки вони належать зазначеному перерахунку.

Ретельно вивчіть синтаксис перерахувань. Не забудьте, що переліки можуть містити методи та поля. Це дуже потужні синтаксичні інструменти, що значно перевершують int за гнучкістю та виразністю. Розглянемо наступний різновид коду нарахування зарплати:

Приклад: C# | Java


Clone this wiki locally