.NET — можете ли вы использовать интерфейс, а когда не должны использовать интерфейс

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

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

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

interface IStringCollection : ICollection<string>
{
}

Я говорю больше что-то вроде:

interface ISomethingProvider
{
  ISomething Provide(ISomethingOptions options);
}

Это действительно сверх меры? я полагаю, что любой тип может выиграть от взаимодействия в какой-то момент ... и единственная реальная проблема, с которой я столкнулся, заключается в том, что мне пришлось изучить то, что я считаю лучшим способом разработки классов, поскольку у вас нет дурака происходят взаимодействия и «взломы».

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

ps - на самом деле это не столько о том, как писать интерфейсы.


person Community    schedule 21.09.2008    source источник


Ответы (10)


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

person Arthur Vanderbilt    schedule 21.09.2008

Короче говоря, да, можно перекрыть интерфейс проекта. Примите во внимание, когда ситуация действительно требует абстрактного базового класса и интерфейса, хотя они оба похожи, использование обоих см. здесь. Обычно я замечал, что люди используют интерфейсы, когда им действительно следует использовать абстрактные базовые классы. С точки зрения объектно-ориентированного программирования интерфейсы должны использоваться для перечисления общего поведения, которое может охватывать совершенно разные классы. Например, у вас может быть интерфейс IMove с методом Move(). Теперь представьте, что у вас есть класс Airplane, Car, Person и Insect. Airplane и Car могут наследоваться от абстрактного класса Vehicle, но все равно должны использовать IMove, как и Insect и Person, но все они реализуют перемещение по-разному. Я заметил, в том числе и я, что люди склонны использовать интерфейсы для «группировки» классов вместе, когда на самом деле это должен обрабатывать базовый класс.

person Marcus King    schedule 21.09.2008
comment
Да, если вы обнаружите, что пишете один и тот же метод для реализации интерфейса двух классов, вам нужен абстрактный базовый класс. - person warren_s; 22.09.2008

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

person Sklivvz    schedule 21.09.2008

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

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

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

person MusiGenesis    schedule 21.09.2008
comment
Прелесть современных инструментов рефакторинга в том, что вам не нужно начинать с интерфейса, чтобы иметь возможность использовать его в будущем. - person Dan Bryant; 13.06.2012

Всякий раз, когда я вижу или слышу, как кто-то говорит это

Интерфейсы описывают контракт на поведение

Я знаю, что нашел кого-то, кто не понимает интерфейсы.

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

Интерфейсы описывают контракт для интерфейса, отсюда и название. У них нет поведения.

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

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

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

person Jim Cooper    schedule 14.08.2009
comment
Я бы сказал, что документированный интерфейс может описывать контракт поведения. Вы можете описать контракт, не обязательно принуждая его к исполнению; разработчик по-прежнему несет ответственность за соблюдение документации. - person Dan Bryant; 13.06.2012

Может быть очень сложно проработать возможный стек вызовов, прежде чем вы начнете работать с отладчиком, если у вас везде есть интерфейсы. Я предпочитаю интерфейсы только тогда, когда:

  1. вам нужно, чтобы члены команды договорились о том, кто и что должен делать, прежде чем они начнут программировать — тогда интерфейс точно документирует границы
  2. когда вам действительно нужен интерфейс для решения проблемы, поэтому по крайней мере две реализации, которые не расширяют друг друга
  3. Вы ожидаете случай 2
person Oskar    schedule 21.09.2008

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

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

person Per Hornshøj-Schierbeck    schedule 21.09.2008

Это касается не только .NET, та же проблема довольно часто возникает в Java.

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

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

person warren_s    schedule 21.09.2008

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

person mattlant    schedule 21.09.2008

Швейцарский армейский нож!

Проконсультируйтесь с этим:

http://thedailywtf.com/Articles/Classic-WTF-Implements-ISwissArmyKnife.aspx

person TonyOssa    schedule 21.09.2008