C# - Добавление систематически является интерфейсом хорошая практика?

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

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

Я неправ? Или действительно ли это - хорошая практика?

Спасибо

10
задан Amokrane Chentir 1 July 2010 в 12:27
поделиться

9 ответов

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

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

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

6
ответ дан 3 December 2019 в 16:09
поделиться

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

7
ответ дан 3 December 2019 в 16:09
поделиться

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

Иногда скучаю по Java :)

0
ответ дан 3 December 2019 в 16:09
поделиться

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

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

5
ответ дан 3 December 2019 в 16:09
поделиться

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

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

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

1
ответ дан 3 December 2019 в 16:09
поделиться

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

На ум приходит agile-концепция: «либо добавляющая ценность, либо принимающая ценность».

Что произойдет, если вы их удалите? Если ничего, тогда ... зачем они там?

В качестве примечания. Интерфейсы чрезвычайно полезны для Rhino Mocks, внедрения зависимостей и так далее ...

1
ответ дан 3 December 2019 в 16:09
поделиться

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

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

Я обычно держу это «в курсе» какое-то время, независимо от того, есть ли у меня интерфейс, базовый класс или и то, и другое, и даже является ли базовый класс абстрактным (обычно это так). Я буду работать над проектом (обычно это решение Visual Studio, в котором содержится от 3 до 10 проектов) какое-то время (возможно, пару дней), прежде чем я проведу рефакторинг и / или попрошу второго мнения. После принятия окончательного решения и рефакторинга и тестирования кода я сообщаю коллегам-разработчикам, что он готов к использованию.

1
ответ дан 3 December 2019 в 16:09
поделиться

Полезно для тестов.

Метод может принимать параметр типа ISomething, и это может быть SqlSomething или XmlSomething, где ISomething - это интерфейс, а SqlSomething и XmlSomething - классы, реализующие интерфейс, в зависимости от того, выполняете ли вы тесты (вы передаете XmlSomething в этом случае) или запуск приложения (SqlSomething).

Кроме того, при создании универсального проекта, который может работать с любой базой данных, но без использования инструмента ORM, такого как LINQ (возможно, потому, что ядро ​​базы данных может не поддерживать LINQ to SQL), вы определяете интерфейсы с помощью методов, которые вы использовать в приложении. Позже разработчики реализуют интерфейсы для работы с базой данных, создадут класс MySQLProductRepository, класс PostgreSQLProductRepository, которые наследуют один и тот же интерфейс, но имеют разную функциональность.

В коде приложения любой метод принимает в качестве параметра объект репозитория типа IProductRepository, который может быть любым.

4
ответ дан 3 December 2019 в 16:09
поделиться

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

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

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

1
ответ дан 3 December 2019 в 16:09
поделиться
Другие вопросы по тегам:

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