Подтвердить что ты не робот

Интерфейсы отделены от реализации класса в отдельных проектах?

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

Мы хотели бы пойти дальше и отделить данные еще больше: мы хотели бы иметь один проект (CSPROJ) с интерфейсом в одном файле .CS плюс еще один .CS файл с помощью классов справки (например, некоторые публичные классы, используемые в этот интерфейс, некоторые перечисления и т.д.). Затем мы хотели бы иметь еще один проект (CSPROJ) с шаблоном factory, реализацией конкретного интерфейса и другими "рабочими" классами.

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

Это решение имеет один большой недостаток: он умножает количество сборок на 2, потому что у вас будет для каждого "нормального" проекта один проект с interace и один с реализацией.

Что бы вы порекомендовали? Считаете ли вы хорошей идеей разместить все интерфейсы в одном отдельном проекте, а не один интерфейс в своем собственном проекте?

4b9b3361

Ответ 1

Я бы различал такие интерфейсы:

  • Автономные интерфейсы, цель которых вы можете описать, не говоря о остальной части вашего проекта. Поместите их в одну выделенную "сборку интерфейса", на которую, вероятно, ссылаются все остальные сборки вашего проекта. Типичные примеры: ILogger, IFileSystem, IServiceLocator.

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

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

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

Мой ответ зависит от понятия, что это нормально, чтобы иметь некоторую связь с классами. Скрытие всего за интерфейсом было бы ошибкой. Иногда это просто "новый" класс, вместо того, чтобы вводить его или создавать его с помощью factory.

Ответ 2

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

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

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

Сложение:

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

Ответ 3

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

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

Ответ 4

Я думаю, вы должны сначала подумать, принадлежат ли ВСЕ интерфейсы к "публичному интерфейсу" вашего проекта.

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

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

Ответ 5

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

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

Ответ 6

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

Здесь очень много соображений: вы пишете библиотеку для разработчиков, развертываете ли вы библиотеки DLL для внешних клиентов, используете ли вы удаленное использование (спасибо, Максимилиан Майерл) или записываете службы WCF и т.д. Нет никого права ответ - это зависит.

В общем, я согласен с Джеффом Sternal - не разбивайте сборки, если это не дает доказанной выгоды.

Ответ 7

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

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

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

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