C # - Является ли систематическое добавление интерфейса хорошей практикой? - PullRequest
10 голосов
/ 01 июля 2010

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

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

Я не прав? Или это хорошая практика?

Thx

Ответы [ 9 ]

7 голосов
/ 01 июля 2010

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

6 голосов
/ 01 июля 2010

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

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

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

5 голосов
/ 01 июля 2010

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

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

4 голосов
/ 01 июля 2010

Это полезно для тестов.

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

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

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

1 голос
/ 02 июля 2010

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

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

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

1 голос
/ 01 июля 2010

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

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

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

1 голос
/ 01 июля 2010

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

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

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

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

1 голос
/ 01 июля 2010

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

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

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

0 голосов
/ 01 июля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...