Если Вы всегда Код К Интерфейсам В [закрытом] Java

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

Я должен кодировать к интерфейсам для каждого класса, который я пишу, или то излишество? Я не хочу удваивать количество исходных файлов в проекте, если это не действительно стоит того.

Какие факторы я могу использовать, чтобы решить, кодировать ли интерфейсом или нет?

36
задан Sandor Murakozi 7 July 2010 в 13:17
поделиться

5 ответов

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

Но не всегда легко заранее знать, что может измениться в будущем, особенно если вы не так опытны. Я думаю, что решением этой проблемы является рефакторинг: держите его простым (= без интерфейса), пока он не нужен. Когда возникает необходимость, просто сделайте рефакторинг «Вводим/Извлекай интерфейс» (поддерживаемый почти всеми приличными АЙД).

При этом извлекайте только те методы, которые действительно нужны вызывающим. Не бойтесь извлекать более одного отдельного интерфейса (если не все извлеченные методы действительно когерентны).

Одним из драйверов рефакторинга может быть тестирование: если вы не можете легко протестировать что-то с классами, рассмотрите возможность введения только одного / некоторых интерфейсов. Это также позволит вам использовать макетирование, которое может значительно упростить тестирование во многих случаях.

Редактировать: Основываясь на комментарии Тарского, я понял еще один важный сценарий/корректировку предыдущих утверждений:
Если вы предоставляете внешний API (для других [под]проектов или действительно выпускаете его «в дикую природу»), то использование интерфейсов в API (за исключением простых классов значений) почти всегда является хорошей идеей.
Это позволит вам изменить impl, если хотите, не нарушая клиентский код. У вас будет проблема только в том случае, если вам также придется изменить интерфейс. Не нарушить совместимость будет очень сложно (если не невозможно).

33
ответ дан 27 November 2019 в 05:59
поделиться

Я использую его, когда верно хотя бы одно из следующего:

1) Я хочу отделить несвязанные модули/классы друг от друга, и хочу, чтобы это было отражено зависимостями пакета java.

2) Когда развязка важна с точки зрения зависимостей сборки

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

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

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

11
ответ дан 27 November 2019 в 05:59
поделиться

Нет, у каждого класса не должно быть интерфейса. Это квадрат излишка.

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

Взгляните на API коллекций java.util в качестве хорошего примера. Интерфейс List - это хорошая абстракция для общей идеи List, но вы можете видеть, что есть много способов реализовать его: ArrayList, LinkedList и т. Д.

ОБНОВЛЕНИЕ: А как насчет того случая, когда вы разрабатываете конкретный класс , после того, как у вас появятся клиенты, решите, что вам нужен интерфейс, а затем вы сломаете своих клиентов, добавив интерфейс? Ага, вот что происходит. Как узнать то, чего не знаешь? Никакое программное обеспечение или методология не могут это исправить.

Хорошая новость для вас заключается в том, что извлечение интерфейса из конкретного класса - это несложный рефакторинг как для вас, так и для ваших клиентов. IDE обычно справляются с подобными вещами. Вы и ваши клиенты должны ими воспользоваться.

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

Объекты модели или значения, такие как Person, Address или Phone, не должны иметь интерфейса. У объекта неизменного значения не должно быть интерфейса.

Остальные попадают в серые зоны. Используйте свое здравое суждение.

9
ответ дан 27 November 2019 в 05:59
поделиться

Мне нравится думать об использовании интерфейсов, когда важны подключаемость и возможность различного поведения. Услуги идеально подходят. Кому-то может понадобиться реализация по умолчанию, но другое - подделка (насмешка) и т. Д. Это, очевидно, означает, что должен быть intf, так как всегда будет как минимум 2 формы.

Типы значений, с другой стороны, должны быть конечными классами. Их нельзя продлевать. Типы значений включают что-то вроде Suburb, MimeType. Если есть варианты, используйте композицию. В качестве цели я стараюсь вкладывать немного поведения, если оно есть, в свои типы значений. Проверка простого типа, который он обертывает, и т. Д., Вероятно, является самым сложным, что он делает. Например, класс Color, который принимает r / g / b, должен проверять, что каждый компонент находится в диапазоне от 0 до 255, и это все.

1
ответ дан 27 November 2019 в 05:59
поделиться

Короче говоря, нет. Вы являетесь создателем приложения, поэтому у вас есть достойное представление о том, что можно изменить. Некоторые книги по паттернам проектирования, на мой взгляд, немного сходят с ума от этого, поскольку они, кажется, всегда подталкивают к проектированию интерфейсов, а не реализации, несмотря ни на что. Иногда это просто излишество. Для моего последнего приложения (небольшого размера) у меня есть интерфейс базы данных, потому что я думаю, что есть шанс, что позже я перенесу его в веб и перейду на MySQL. Конечно, в действительности, было бы легко создать интерфейс базы данных на основе существующего класса и просто добавить "implements myDbInterface" позже с парой небольших изменений. Однако это работает, потому что я единственный разработчик. В более крупной команде или при другом типе продукта ответ может быть другим. Просто используйте свое лучшее суждение (после прочтения всех хороших ответов SO, конечно).

2
ответ дан 27 November 2019 в 05:59
поделиться
Другие вопросы по тегам:

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