Соглашение об именах интерфейсов Java / Реализация

Как вы называете разные classы / интерфейсы, которые вы создаете? Иногда у меня нет информации о реализации, чтобы добавить к имени реализации – как интерфейс FileHandler и class SqlFileHandler .

Когда это происходит, я обычно TruckClass интерфейс «обычным» именем, например Truck и TruckClass фактический class TruckClass .

Как вы называете интерфейсы и classы в этом отношении?

Назовите свой Interface что это такое. Truck . Не ITruck потому что это не ITruck это Truck .

Interface в Java – это тип . Затем у вас есть DumpTruck , TransferTruck , WreckerTruck , CementTruck и т. WreckerTruck , CementTruck implement Truck .

Когда вы используете Interface вместо подclassа, вы просто бросаете его в Truck . Как в List . Поставить I впереди – это просто дерьмовая тотализация, которая добавляет ничего, кроме всего, что нужно набрать для вашего кода.

Все современные Java IDE-метки «Интерфейсы и реализации» и что не без этой глупой нотации. Не называйте это TruckClass тавтологией так же плохо, как тавтология IInterface .

Если это реализация, это class. Единственное реальное исключение из этого правила, и всегда есть исключения, может быть чем-то вроде AbstractTruck . Поскольку только подclassы когда-либо видят это, и вы никогда не должны бросать его в class Abstract он добавляет некоторую информацию о том, что class является абстрактным и как его следует использовать. Вы могли бы придумать лучшее имя, чем AbstractTruck и использовать BaseTruck или DefaultTruck вместо этого, поскольку abstract находится в определении. Но поскольку Abstract classы никогда не должны быть частью какого-либо открытого интерфейса, я считаю, что это приемлемое исключение из правила. Обеспечение protected конструкторов имеет большое значение для преодоления этого разрыва.

И суффикс Impl – это еще больше шума. Больше тавтологии. Все, что не является интерфейсом, представляет собой реализацию, даже абстрактные classы, которые являются частичными реализациями. Собираетесь ли вы наложить этот глупый суффикс Impl на каждое имя каждого classа ?

Interface – это контракт на то, что должны поддерживать общедоступные методы и свойства, а также информация о типе . Все, что реализует Truck – это тип Truck .

Посмотрите на стандартную библиотеку Java. Вы видите IList , ArrayListImpl , LinkedListImpl ? Нет, вы видите List и ArrayList и LinkedList . Вот хорошая статья об этом точном вопросе. Любые из этих глупых соглашений о присвоении имен префиксов / суффиксов все также нарушают принцип DRY .

Кроме того, если вы обнаружите, что добавляете DTO , JDO , BEAN или другие глупые повторяющиеся суффиксы к объектам, то они, вероятно, принадлежат к пакету, а не ко всем этим суффиксам. Правильно упакованные пространства имен являются собственными документами и уменьшают всю бесполезную избыточную информацию в этих действительно плохо продуманных проприетарных схемах именования, которые большинство мест даже не придерживаются единообразно.

Если все, что вы можете придумать, чтобы сделать ваше имя Class уникальным, суффиксирует его с помощью Impl , тогда вам нужно переосмыслить наличие Interface вообще. Поэтому, когда у вас есть ситуация, когда у вас есть Interface и единая Implementation которая не уникально специализируется на Interface вам, вероятно, не нужен Interface .

Я видел ответы здесь, которые предполагают, что если у вас есть только одна реализация, вам не нужен интерфейс. Это летит перед лицом принципа «Инжекция / инверсия принципа подчинения» (не звоните нам, мы позвоним вам!).

Итак, есть ситуации, в которых вы хотите упростить свой код и сделать его легко проверяемым, полагаясь на внедренные реализации интерфейса (которые также могут быть проксированы – ваш код не знает!). Даже если у вас есть только две реализации: одна – Mock для тестирования, и одна, которая вводится в фактический производственный код, – это не делает излишним интерфейс. Хорошо документированный интерфейс устанавливает контракт, который также может поддерживаться строгой реализацией для тестирования.

на самом деле вы можете установить тесты, в которых mocks реализует самый строгий контракт на интерфейс (бросая исключения для аргументов, которые не должны быть нулевыми и т. д.), и ловить ошибки при тестировании, используя более эффективную реализацию в производственном коде (не проверяя аргументы, которые должны не должно быть null за то, что оно было нулевым, поскольку mock выбрасывало исключения в ваших тестах, и вы знаете, что аргументы не являются нулевыми из-за исправления кода после этих тестов, например).

Injection Dependency / IOC может быть трудно понять для новичков, но как только вы поймете его потенциал, вы захотите использовать его повсюду, и вы будете постоянно создавать интерфейсы – даже если их будет только один ( фактическое производство) осуществление.

Для этой одной реализации (вы можете сделать вывод, и вы будете правы, что я считаю, что mocks для тестирования следует называть Mock (InterfaceName)), я предпочитаю имя Default (InterfaceName). Если произойдет более конкретная реализация, ее можно назвать соответствующим образом. Это также исключает суффикс Impl, который мне особенно не нравится (если это не абстрактный class, OF COURSE это «impl»!).

Я также предпочитаю «Base (InterfaceName)» в отличие от «Abstract (InterfaceName)», потому что есть некоторые ситуации, в которых вы хотите, чтобы ваш базовый class стал доступен позже, но теперь вы застряли с именем «Abstract (InterfaceName)» , и это заставляет вас переименовать class, возможно, вызвав небольшую путаницу, но если бы он всегда был Base (InterfaceName), удаление абстрактного модификатора не меняло бы class.

Имя интерфейса должно описывать абстрактную концепцию, представляемую интерфейсом. Любой class реализации должен иметь какие-то специфические черты, которые можно использовать, чтобы дать ему более конкретное имя.

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

Я склонен следовать псевдо-соглашениям, установленным Java Core / Sun, например, в classах Collections:

  • List – интерфейс для «концептуального» объекта
  • ArrayList – конкретная реализация интерфейса
  • LinkedList – конкретная реализация интерфейса
  • AbstractList – абстрактная «частичная» реализация для поддержки пользовательских реализаций

Я использовал то же самое, что и моделирование classов событий после парадигмы AWT Event / Listener / Adapter.

Стандартное соглашение C #, которое достаточно хорошо работает и на Java, – это префикс всех интерфейсов с I – поэтому ваш интерфейс обработчика файлов будет IFileHandler а ваш интерфейс грузовика будет ITruck . Это непротиворечиво, и позволяет легко рассказать интерфейсы из classов.

Мне нравятся имена интерфейсов, которые указывают, какой контракт описывает интерфейс, например «Comparable» или «Serializable». Существительные типа «Грузовик» на самом деле не описывают грузовик – каковы Способности грузовика?

Что касается конвенций: я работал над проектами, где каждый интерфейс начинается с «I»; в то время как это несколько чуждо к соглашениям Java, это делает поиск интерфейсов очень легким. Кроме того, суффикс «Impl» является разумным именем по умолчанию.

Некоторым людям это не нравится, и это скорее соглашение .NET, чем Java, но вы можете назвать свои интерфейсы с префиксом капитала I, например:

 IProductRepository - interface ProductRepository, SqlProductRepository, etc. - implementations 

Люди, выступающие против этого соглашения об именах, могут утверждать, что вам все равно, работаете ли вы с интерфейсом или объектом в коде, но мне легче читать и понимать «на лету».

Я бы не назвал class реализации суффиксом classа. Это может привести к путанице, поскольку вы действительно можете работать с объектами classа (т.е. типа) в своем коде, но в вашем случае вы не работаете с объектом classа, вы просто работаете с простым старым объектом ,

TruckClass звучит как class Truck , я думаю, что рекомендуемое решение – добавить суффикс Impl . На мой взгляд, лучшее решение состоит в том, чтобы содержать внутри имени реализации некоторую информацию, что происходит в этой конкретной реализации (например, у нас есть с интерфейсом и реализациями List : ArrayList или LinkedList ), но иногда у вас есть только одна реализация и должны иметь интерфейс из-за к удаленному использованию (например), то (как упоминалось в начале) Impl является решением.

Я использую оба соглашения:

Если интерфейс является конкретным экземпляром aa хорошо известного шаблона (например, Service, DAO), тогда ему может не понадобиться «I» (например, UserService, AuditService, UserDao), все работают нормально без «I», поскольку пост-исправление определяет мета-шаблон.

Но если у вас есть что-то одноразовое или двухкратное (обычно для шаблона обратного вызова), то это помогает отличить его от classа (например, IAsynchCallbackHandler, IUpdateListener, IComputeDrone). Это интерфейсы специального назначения, предназначенные для внутреннего использования, иногда IInterface обращает внимание на то, что операнд на самом деле является интерфейсом, поэтому на первый взгляд сразу становится ясно.

В других случаях вы можете использовать I, чтобы избежать столкновения с другими общеизвестными конкретными classами (ISubject, IPrincipal vs Subject или Principal).

  • Сингулярные или множественные имена controllerов и помощников в Rails
  • Как переопределить соглашения об именах rails?
  • Какую страtagsю вы используете для именования пакетов в проектах Java и почему?
  • Interesting Posts

    Dd – просто скопируйте разделы

    Добавить новые элементы в начало списка на Android?

    Почему Windows требует перезагрузки намного больше, чем Linux?

    Почему C ++ не упрощает структуру?

    Как преобразовать List в строку с разделителями-запятыми без повторения списка явно

    Как я могу изменить или заменить все экземпляры символа в текстовом файле на новую строку / разрыв строки / EOL в Notepad2 или Notepad ++?

    Предотвратить показ веб-страницы «веб-страница недоступна»

    Используются ли примитивы Java в стеке или куче?

    EF Code First “Недопустимое имя столбца« Дискриминатор », но без наследования

    Как получить строку запроса из текущего URL-адреса с помощью JavaScript?

    Как принудительно удалить заблокированный файл, который не имеет блокировки в Windows?

    MSVCR100.dll отсутствует ошибка даже там

    Является ли 1.0 действительным выходом из std :: generate_canonical?

    Файлы Maven имеют .lastUpdated как расширение

    Как перенести мой старый ключ PGP на более безопасный алгоритм?

    Давайте будем гением компьютера.