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

В каком пространстве имен вы должны помещать интерфейсы относительно своих разработчиков?

В частности, когда вы создаете пару интерфейса/реализации, и нет никакой главной организационной проблемы (например, интерфейс должен идти в другой сборке, то есть, как рекомендовано архитектурой s #), у вас есть способ организации по умолчанию их в вашей схеме пространства имен/имен?

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

4b9b3361

Ответ 1

Ответ зависит от ваших намерений.

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

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

Ответ 2

Я обычно поддерживаю интерфейс в том же пространстве имен, что и конкретные типы.

Но это просто мое мнение и макет пространства имен очень субъективны.

Animals
|
| - IAnimal
| - Dog
| - Cat
Plants
|
| - IPlant
| - Cactus

На самом деле вы ничего не получаете, перемещая один или два типа из основного пространства имен, но вы добавляете требование для одного дополнительного оператора using.

Ответ 3

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

Interfaces
|--IAnimal
|--IVegetable
|--IMineral
MineralImplementor
Organisms
|--AnimalImplementor
|--VegetableImplementor

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

Ответ 4

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

На стороне примечания, я сильно не люблю соглашение .NET о предваряющих именах интерфейса с буквой "I." Дело в том, что интерфейсные модели (I) Foo не являются ifoo, это просто foo. Так почему я не могу просто назвать это Foo? Затем я называю классы реализации, например, AbstractFoo, MemoryOptimizedFoo, SimpleFoo, StubFoo и т.д.

Ответ 5

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

Что касается пространств имен, я храню их в BusinessCommon.Interfaces.

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

Ответ 6

Я НЕНАВИЖУ, когда я нахожу интерфейсы и реализации в одном пространстве имен/сборке. Пожалуйста, не делайте этого, если проект развивается, это боль в заднице для рефакторинга.

Когда я ссылаюсь на интерфейс, я хочу его реализовать, а не для всех его реализаций.

Что может быть допустимым, так это поместить интерфейс со своим классом зависимостей (класс , который ссылается на интерфейс).

EDIT: @Джош, я только что прочитал последнее предложение, это сбивает с толку! конечно, как класс зависимостей, так и тот, который его реализует, ссылается на интерфейс. Чтобы я убедился, я приведу примеры:

Допустимо:

Интерфейс + реализация:

namespace A;

   Interface IMyInterface
   {
       void MyMethod();
   }

namespace A;

   Interface MyDependentClass
   {
       private IMyInterface inject;

       public MyDependentClass(IMyInterface inject)
       {
           this.inject = inject;
       }

       public void DoJob()
       {
           //Bla bla
           inject.MyMethod();
       }
   }

Реализация класса:

namespace B;

   Interface MyImplementing : IMyInterface
   {
       public void MyMethod()
       {
           Console.WriteLine("hello world");
       }
   }

НЕ ПРИНИМАЕТСЯ:

namespace A;

   Interface IMyInterface
   {
       void MyMethod();
   }

namespace A;

   Interface MyImplementing : IMyInterface
   {
       public void MyMethod()
       {
           Console.WriteLine("hello world");
       }
   }

И НЕ СОЗДАВАЙТЕ проект/мусор для ваших интерфейсов! Пример: ShittyProject.Interfaces. Вы пропустили точку!

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

Ответ 7

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

Ответ 8

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

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

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

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

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

Ответ 9

Я даю свой собственный опыт, который противоречит другим ответам.

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

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

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

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

Итак, спросите себя, действительно ли вы моделируете тип или структуру.