Имена имеют возможность передать смысл. Почему вы отказались от этой возможности с Impl?
Прежде всего, если у вас когда-либо будет только одна реализация, покончите с интерфейсом. Это создает проблему именования и ничего не добавляет. Хуже того, это может вызвать проблемы с непоследовательными сигнатурами методов в API, если вы и все другие разработчики не будете осторожны, чтобы всегда использовать только интерфейс.
Учитывая это, мы можем предположить, что каждый интерфейс имеет или может иметь две или более реализации.
Если у вас есть только один в данный момент, и вы не знаете, чем другой может отличаться, по умолчанию хорошее начало.
Если у вас есть два прямо сейчас, назовите каждого в соответствии с его назначением.
Пример: недавно у нас был конкретный класс Context (применительно к базе данных). Было понято, что нам нужно иметь возможность представлять контекст, находящийся в автономном режиме, поэтому имя «Контекст» использовалось для нового интерфейса (для обеспечения совместимости для старых API), и была создана новая реализация, OfflineContext . Но угадайте, во что переименовали оригинал? Это верно, ContextImpl (yikes).
В этом случае DefaultContext , вероятно, будет в порядке, и люди получат его, но это не так наглядно, как могло бы быть. В конце концов, если это не в автономном режиме , что это? Итак, мы пошли с: OnlineContext .
Особый случай: использование префикса «I» на интерфейсах
Один из других ответов предложил использовать префикс I на интерфейсах. Предпочтительно, вам не нужно это делать.
Однако, если вам нужны оба интерфейса для пользовательских реализаций, но у вас также есть основная конкретная реализация, которая будет часто использоваться, и его базовое название слишком просто, чтобы отказаться от одного интерфейса, тогда вы можете рассмотреть возможность добавления «Я» к интерфейсу (хотя, это совершенно нормально, если он по-прежнему не подходит для вас и вашей команды).
Пример: многие объекты могут быть «EventDispatcher». Ради API это должно соответствовать интерфейсу. Но вы также хотите предоставить основной диспетчер событий для делегирования. DefaultEventDispatcher будет в порядке, но он будет немного длинным, и если вы собираетесь часто видеть его имя, вы можете использовать базовое имя EventDispatcher для конкретного класса и реализовать IEventDispatcher для пользовательских реализаций:
/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
/* default event dispatcher */
}
/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
/* default event dispatcher. */
}
if you will only ever have one implementation, do away with the interface
- если вы не хотите протестировать компонент, в этом случае вы можете сохранить этот интерфейс для создания MockOrder, OrderStub или аналогичного.Я определяю наименование в зависимости от варианта использования интерфейса.
Если интерфейс используется для развязки , то я выбираю
Impl
реализации.Если целью интерфейса является поведенческая абстракция , то реализации именуются в соответствии с тем, что они конкретно делают. Я часто добавляю имя интерфейса к этому. Так что если интерфейс называется
Validator
, я используюFooValidator
.Я считаю, что
Default
это очень плохой выбор. Во-первых, это загрязняет возможности завершения кода, потому что имена всегда начинаются с него. Другое дело, что значение по умолчанию может меняться со временем. Так что то, что сначала может быть значением по умолчанию, может через некоторое время быть устаревшей функцией. Так что либо вы всегда начинаете переименовывать свои классы, как только изменяются значения по умолчанию, либо вы живете с вводящими в заблуждение именами.источник
Я согласен с ответом Николь (в частности, что интерфейс, вероятно, не нужен в большинстве случаев), но для обсуждения я выброшу дополнительную альтернативу, кроме
OrderImpl
иDefaultOrder
: скрыть реализацию за статическим фабричным методом, напримерOrders.create()
. Например:При таком подходе реализация может быть анонимным внутренним классом или частным классом с
Default
Impl
именем или в имени, или он может быть полностью назван как-то иначе. Какой бы выбор не был сделан, вызывающему абоненту не нужно заботиться, поэтому вы получаете больше гибкости сейчас и позже, когда / если вы решите изменить его.Некоторые большие примеры этой модели на практике являются
java.util.Collections
иjava.util.concurrent.Executors
классами полезности, чьи методы возвращают скрытые реализации. Как упоминает Effective Java (в пункте 1), этот шаблон может помочь уменьшить «концептуальный вес» API.источник
Я всегда говорю
OrderImpl
просто потому, что он отображается в алфавитном порядке сразу послеOrder
интерфейса.источник
Вы можете назвать интерфейс с префиксом I (IWhзна), а затем сделать реализацию как угодно.
Официальные соглашения по Java-коду не говорят об этом типе именования для интерфейсов, однако этот тип именования помогает распознавать и перемещаться.
источник
Я думаю, что хотя Default может иметь смысл в некоторых случаях, было бы более полезно описать реализацию. Итак , если ваш интерфейс ,
UserProfileDAO
то ваши реализации могут бытьUserProfileSQLDAO
илиUserProfileLDAPDAO
или что - то подобное.источник
если возможно, назовите его после того, что / как он делает свое дело.
обычно худший подход - называть его после того, как он должен использоваться.
Если предполагается, что он будет использоваться в качестве базового класса для реализации, вы можете использовать BaseX или AbstractX (если он абстрактный), но попробуйте сжать то, что он делает, потому что, если он ничего не делал, вы бы его не создали, у вас уже есть интерфейс). Если он обеспечивает простейшую возможную функциональность и ожидается, что он будет использоваться напрямую (не расширяя его), когда такой функциональности достаточно, вы можете назвать ее SimpleX или BasicX.
Если он используется, если не предоставлена другая реализация, назовите его DefaultX
источник
Большинство из этих ответов описывают, что делается, но не почему.
Что случилось с принципами ОО? Что Impl говорит мне о классе и как его использовать? Вы должны быть обеспокоены пониманием использования, а не того, как оно построено.
Если я создаю интерфейс Person, что такое PersonImpl? Бессмысленно. По крайней мере, DefaultPerson говорит мне, кто бы ни закодировал его, он не должен был создавать интерфейс.
Интерфейсы набирают полиморфизм и должны использоваться как таковые.
источник