(Программирование интерфейса против работы с конкретным классом), когда есть только один конкретный класс

В объектно-ориентированном компоненте, когда у вас есть только одна реализация, доступная для класса, и этот класс не «опубликован» для других компонентов, целесообразно ли иметь интерфейс и вместо этого работать с интерфейсом?

Я полностью ознакомлен с принципом проектирования «программирование для интерфейса», а также широко его использую.

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

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

Что вы думаете?


person user170272    schedule 08.09.2009    source источник
comment
Возможный обман - stackoverflow.com/questions/720115/   -  person Nate    schedule 08.09.2009


Ответы (6)


Насколько мне известно, есть три ситуации, когда использование интерфейса оправдано:

  1. Это часть архитектуры (я признаю, что она не очень четко определена).
  2. У вас более 1 реализации.
  3. Это общедоступный интерфейс.

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

person Buhb    schedule 08.09.2009

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

Это не всегда будет целесообразно, но об этом стоит подумать, когда вы пытаетесь решить. Как вы думаете, вам нужно тщательно протестировать этот класс/объект? Если вы думаете, что будете, может быть намного проще иметь дело с интерфейсом, а не с конкретным классом.

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

person Joseph    schedule 08.09.2009
comment
Согласен, в последнее время я ухожу от вопроса «какое решение является наиболее проверяемым и воспроизводимым»? Размышление об этом позволило моей кодовой базе быть намного проще и в то же время очень сильно зависеть от интерфейсов на самых важных фронтах. - person nyxtom; 08.09.2009
comment
И EasyMock, и JMock поддерживают насмешку над классом, поэтому аргумент тестирования является немым, имхо. - person Nick Holt; 08.09.2009
comment
Это, как правило, помещает вас в интерфейсный ад. Если вам не нужно объявлять свои методы окончательными, вы можете использовать расширение класса easymock. Если это не вариант, вы можете использовать powermock. Сегодня нет оправдания добавлению интерфейсов только для того, чтобы упростить тестирование. По крайней мере, не в описанных выше обстоятельствах. - person Buhb; 08.09.2009
comment
Если вы находитесь в интерфейсном аду, вы, вероятно, не используете ReSharper. Перейти к реализации избавляет от боли. :) - person TrueWill; 08.09.2009
comment
С интерфейсным адом проблем больше, чем с тем, что решается с помощью перехода к реализации. Добавление общедоступного метода означает добавление его в двух местах. Вам нужно объявить что-то дважды, а не один раз, что является пустой тратой времени. Кроме того, само существование интерфейса сообщает о том, что реализующий класс(ы) имеет роль, и будущие разработчики могут задаться вопросом, должен ли недавно добавленный публичный метод быть частью этой роли или нет. - person Buhb; 08.09.2009

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

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

person Andrew Hare    schedule 08.09.2009
comment
+1 b/c при переходе от неиспользования интерфейса к использованию интерфейса это может оказаться невозможным, если это часть вашего общедоступного API, и вы выпустили свой код для внешних пользователей. - person Shizzmo; 08.09.2009

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

person Kevin    schedule 08.09.2009
comment
Я согласен. Просто не забудьте надеть шляпу клиента при разработке - если ваш класс будет использоваться другими, они будут проклинать вас, если вы не предоставите интерфейс. Вам это может не понадобиться, но они будут, если у класса есть какие-либо важные функции/зависимости. - person SingleShot; 08.09.2009
comment
@SingleShot Согласен, это зависит от типа программного обеспечения, которое вы пишете. Многие прикладные программы написаны без учета внешних участников. - person Kevin; 08.09.2009

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

person Nate    schedule 08.09.2009

Как правило: нет. Вам не нужен интерфейс, если вы просто внедряете функциональность один раз. У интерфейсов, как и у всего, есть компромисс: они требуют дополнительной работы (стоимости) и могут приносить дополнительные преимущества. Если затраты перевешивают выгоду, вам, вероятно, не стоит этого делать!

person O'Rooney    schedule 07.09.2011