Недавно я углубился в более «организованное» программирование и узнал, что я должен программировать для интерфейса, а не для реализации. Имея это в виду, было бы лучше "набросать" проект в интерфейсах, прежде чем писать реализацию для него, где это возможно?
И если это так, то в случае использования сторонних библиотек (например, Lidgren) я должен также обернуть их в интерфейсы и разрешить их через контейнеры IOC, или это нормально, чтобы выставить их интерфейсам?
c#
design
interfaces
third-party-libraries
inversion-of-control
Дэн Кладовая
источник
источник
Ответы:
К сожалению, вы обнаружите, что это часто сводится к личным предпочтениям.
То, что вы описали до сих пор, кажется хорошим. На самом деле, если вы хотите (и я рекомендую это), вы можете использовать следующий подход:
Вы концентрируетесь на попытке написать более «организованный» код. Следующий TDD поможет вам в этом.
Некоторые дополнительные очки:
источник
Да, вы должны кодировать против интерфейсов, а не известных реализаций, и да, вы должны сначала создавать интерфейсы, а не заставлять их появляться из вашего собственного кода.
Причины обеих рекомендаций в значительной степени одинаковы: компьютерное программирование в основном связано с человеческими факторами. Многие находят это удивительным, но считают: существует почти бесконечное количество различных способов решения одной и той же вычислительной проблемы, которые работают одинаково хорошо. Почти все из них совершенно невозможно понять тем, кто их не написал (или, фактически, автору вскоре).
Из этого следует, что хорошая программная инженерия в основном заключается в том, как достичь желаемого эффекта (правильных вычислений с разумной эффективностью) таким образом, чтобы впоследствии можно было работать с исходным кодом. Интерфейсы и API являются важной частью этой дисциплины: они позволяют вам думать о проблеме на одном уровне описания одновременно. Это гораздо проще, чем думать о правилах согласованности бизнеса и о реализации связанных списков одновременно, и поэтому навязывать такое разделение интересов принудительно лучше, чем разрешать клиентскому программисту использовать ваш код так, как ему нравится.
В это трудно поверить многим ковбойским программистам, которые убеждены, что они понимают все, что пишут, гораздо лучше, чем обычные мыслители, и могут справиться со всей сложностью, которая доставляет «меньшим» проблемам программистам. Незнание собственных когнитивных ограничений является чрезвычайно распространенным явлением, поэтому лучшие практики организации кода так важны (и часто игнорируются).
Повторим, интерфейсы и API-барьеры в значительной степени хороши , даже если вы сотрудничаете только с самим собой. Что касается внешних библиотек, то, если они содержат хорошо продуманный API, я не вижу проблем в его использовании, поскольку вы не ожидаете замены этой библиотеки на другую. В противном случае, обертка или антикоррупционный слой могут быть очень хорошей идеей.
источник
IBlah
реализованныеBlah
илиBlah
реализованныеBlahImpl
. Мне не нравятся оба, и я склонен использоватьBlah
реализованныйOralBlah
,WrittenBlah
илиASLBlah
. Но, как обычно, более важно соответствовать существующей кодовой базе и ожиданиям, чем любому общему стандарту.Вместо того, чтобы рабски просто программировать интерфейсы, почему бы не заглянуть в Test Driven Development / Design (TDD)?
Многие люди считают TDD практикой тестирования, но на самом деле это конструктивный подход, при котором тесты показывают, как ваш код будет использоваться с помощью тестов (первоначально с помощью модульных тестов, но также с помощью интеграционных тестов).
Программирование на интерфейсах является важным оружием в вашем наборе инструментов, но, как и большинство вещей, это не всегда подходящее решение / техника / практика, поскольку это не всегда необходимо. Вы должны программировать на интерфейсы, где вам нужно.
Использование TDD заставит вас исследовать, где такие интерфейсы важны, а где, честно говоря, не имеет значения. И в конце у вас должен быть довольно хороший набор модульных тестов по всей вашей кодовой базе.
Что касается использования сторонних библиотек, я настоятельно рекомендую оборачивать их в свои абстракции, где это уместно; и не позволяйте клиентам вашего API «знать» о них.
Удачи!
[править: видел ответ megaflight - полностью согласен]
источник
Я думаю, что это излишне. Если пользователя вашего API не нужно заставлять реализовывать / использовать что-то определенным образом, то я бы не учел это. Интерфейсы - это контракты, если мне это не нужно, зачем мне их?
Я думаю, что люди злоупотребляют интерфейсами. Вы добавляете слой сложности, который не нужен в большинстве случаев.
источник
Программирование против контракта - почти всегда хорошая идея. Этот контракт не должен быть интерфейсом, он может быть выполнен классом. По моему мнению, интерфейсы стали несколько перегружены вместе с DI из-за проблем с модульным тестированием и фреймворками.
Лично я предпочитаю вводить интерфейсы только тогда, когда у меня может быть более 1 реализации контракта. Интерфейсы отлично подходят для репозиториев, где я хочу абстрагироваться от доступа к данным, но, вероятно, не так для моей стандартной бизнес-логики, которая, вероятно, будет относительно негибкой.
Теперь отсутствие интерфейса может вызвать проблемы с модульным тестированием, особенно для пуристов. Но я заинтересован в том, чтобы высмеивать внешние зависимости моих программ, а не их внутренние зависимости. Я хочу, чтобы мои тесты выполняли проверку кода, а не отражали структуру кода.
источник