Методология Интерфейсов Java: каждый класс должен реализовать интерфейс?

Я программировал в Java для нескольких курсов в Университете, и у меня есть следующий вопрос:

Методологически признано, что каждый класс должен реализовать интерфейс? Это считают плохой практикой, чтобы не сделать так? Можно ли описать ситуацию, где это не хорошая идея использовать интерфейсы?

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

19
задан BalusC 17 April 2010 в 18:20
поделиться

12 ответов

Вам не нужно создавать интерфейс, если вы не собираетесь его использовать.

Обычно интерфейс требуется, когда:

  • Ваша программа предоставляет несколько реализаций для вашего компонента. Например, реализация по умолчанию, которая является частью вашего кода, и фиктивная реализация, которая используется в тесте JUnit. Некоторые инструменты автоматизируют создание макета реализации, например, EasyMock.
  • Вы хотите использовать внедрение зависимостей для этого класса с такой структурой, как Spring или JBoss Micro-Container. В этом случае рекомендуется указать зависимости одного класса от других классов с помощью интерфейса.
24
ответ дан 30 November 2019 в 02:06
поделиться

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

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

  • Я видел некоторые продукты, которые раскрывали почти все функции интерфейса, просто потребовалось слишком много времени, чтобы понять ненужную сложность.

0
ответ дан 30 November 2019 в 02:06
поделиться

Хороший способ изучить то, что считается хорошими методологиями, особенно когда речь идет о проектировании структуры кода, - это посмотреть на свободно доступный код. В случае Java очевидным примером является рассмотрение системных библиотек JDK .

Вы найдете множество примеров классов, которые не реализуют никаких интерфейсов или предназначены для прямого использования, например java.util.StringTokenizer.

1
ответ дан 30 November 2019 в 02:06
поделиться

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

3
ответ дан 30 November 2019 в 02:06
поделиться

Каждый класс реализует интерфейс (т. Е. Контракт), поскольку он предоставляет неперсонализированный API. Следует ли вам выбрать представление интерфейса отдельно как интерфейса Java, зависит от того, является ли реализация «изменчивой концепцией».

Если вы абсолютно уверены, что существует только одна разумная реализация, тогда нет необходимости в интерфейсе. В противном случае интерфейс позволит вам изменить реализацию без изменения клиентского кода.

Некоторые люди будут кричать «YAGNI», предполагая, что у вас есть полный контроль над изменением кода, если вы обнаружите новое требование позже. Другие люди будут справедливо опасаться, что им потребуется изменить неизменяемый - опубликованный API.

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

Можете ли вы описать ситуацию, когда использование интерфейсов не является хорошей идеей?

В некоторых языках (например, C ++, C #, но не Java) вы можете получить повышение производительности, если ваш класс не содержит виртуальных методов.

В небольших программах или приложениях без опубликованных API вы можете столкнуться с небольшими затратами на поддержку отдельных интерфейсов.

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

7
ответ дан 30 November 2019 в 02:06
поделиться

Использование интерфейса сделает структуру вашего приложения устойчивой к изменениям. Поскольку, как я уже упоминал здесь ( Дебаты о множественном наследовании II: согласно Страуструпу ), множественное наследование было отменено в java и C #, о чем я сожалею, всегда следует использовать интерфейс, потому что вы никогда не знаете, каким будет будущее.

-5
ответ дан 30 November 2019 в 02:06
поделиться

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

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

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

Я действительно заметил, что программисты на C, впервые перешедшие на Java, склонны любить множество интерфейсов («это как заголовки»). Текущая версия Eclipse поддерживает это, позволяя при навигации с нажатой клавишей Control создать всплывающее окно с запросом интерфейса или реализации.

4
ответ дан 30 November 2019 в 02:06
поделиться

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

2
ответ дан 30 November 2019 в 02:06
поделиться

Чтобы ответить на вопрос ОП очень прямо: нет, не всем классам нужны реализовать интерфейс. Как и во всех вопросах дизайна, это сводится к здравому смыслу. Вот несколько полезных правил, которым я обычно следую:

  • Чисто функциональные объекты, вероятно, не нуждаются в этом (например, Pattern, CharMatcher - даже если последний реализует Предикат, он вторичен по отношению к его основной функции)
  • Чистые держатели данных, вероятно, не нуждаются в (например, LogRecord, Locale)
  • Если вы можете представьте себе другую реализацию заданной функции (например, кэш в памяти или кэш на диске), попытайтесь изолировать функциональность в интерфейс. Но и не заходите слишком далеко, пытаясь предсказать будущее.
  • В целях тестирования очень удобно, когда классы, выполняющие ввод-вывод или запускающие потоки, легко подделать, чтобы пользователи не платили штраф, когда { {1}} проводят свои тесты.
  • Нет ничего хуже, чем интерфейс, в котором отсутствует базовая реализация. Обратите внимание на то, где вы проводите линию, и убедитесь, что Javadoc вашего интерфейса в этом отношении нейтрален. Если это не так, вам, вероятно, не нужен интерфейс.
  • Как правило, говоря, для классов, предназначенных для общего пользования вне вашего пакета / проекта, предпочтительно реализовывать интерфейсы, чтобы ваш {{1} } пользователи в меньшей степени связаны с вашей реализацией в течение всего дня.

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

2
ответ дан 30 November 2019 в 02:06
поделиться

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

Если вашей программе в настоящее время не требуется иметь более одной реализации для данного класса, тогда вам не нужен интерфейс. Например, в простой шахматной программе, которую я написал, мне нужен только один тип объекта Board. Шахматная доска - это шахматная доска - это шахматная доска. Для создания интерфейса Board и его реализации потребовалось бы больше кода для написания и поддержки.

Так легко переключиться на интерфейс, если он вам понадобится.

6
ответ дан 30 November 2019 в 02:06
поделиться

Если вы используете шаблон интерфейса поставщика услуг в своем приложении, интерфейсы сложнее расширить, чем абстрактные классы. Если вы добавляете метод в интерфейс, все поставщики услуг должны быть переписаны. Но если вы добавите неабстрактный метод к абстрактному классу, ни один из поставщиков услуг не должен быть переписан.

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

1
ответ дан 30 November 2019 в 02:06
поделиться

Следуя принципу YAGNI a class должен реализовывать интерфейс, если он вам действительно нужен. Иначе что вы от этого выиграете?

Edit: Интерфейсы предоставляют своего рода абстракцию. Они особенно полезны, если вы хотите обмениваться данными между различными реализациями (многие классы реализуют один и тот же интерфейс). Если это всего лишь один класс, то выгоды нет.

21
ответ дан 30 November 2019 в 02:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: