Интерфейсы должны знать об Объектах области?

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

Я должен сопротивляться и попытаться сохранить интерфейсы независимыми от объектов области, или действительно ли это - необоснованное беспокойство?

РЕДАКТИРОВАНИЕ - после регистрации вопроса, я думал об определении интерфейса для каждого объекта области, этот способ, которым они могут разделенный - не знает, является ли это излишество или если это - цена для оплаты так, они остаются независимыми.

РЕДАКТИРОВАНИЕ № 2 - меня попросили дать пример, таким образом, я попытаюсь сохранить это простым. У меня есть процесс, который обрабатывает преобразование изображений, и один из моих объектов области является классом, который содержит информацию, такую как разрешение, список страниц, хеша, и т.д. Позвольте ему быть названным DocumentInfo. У меня есть класс, который использует DocumentInfo для выполнения действий, таких как GeneratePdfFromTiff; я определил GeneratePdfFromTiff сначала как метод интерфейса IImageHandler, который затем реализован ImageHandler.

Проблема - одним из параметров к GeneratePdfFromTiff является DocumentInfo. Здесь мне определили метод на интерфейсном уровне, имеющем необходимость знать о DocumentInfo, который был определен на доменном уровне. Это - вид зависимости, которой я обеспокоен.

8
задан Otávio Décio 5 March 2010 в 16:59
поделиться

4 ответа

Это сложный вопрос, я попробую. +1 за вопрос.

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

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

Поэтому я сомневаюсь, что слишком сильно изолировать их зависимости.

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

Конечно, некоторые «естественные границы владений» все еще должны быть изолированы. Если вы создаете социальный текстовый редактор, все классы предметной области, которые также встречаются в традиционном текстовом редакторе, должны быть полностью изолированы от элементов, связанных с социальными сетями. Таким образом, текстовый редактор должен знать только IUser . Но, полагаю, я не скажу тебе ничего нового ...

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

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

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

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

Я определенно рекомендую вам извлекать интерфейсы из тех объектов домена, которые вы хотели бы использовать вместе со своими интерфейсами.

Если у вас уже есть класс с именем Foo , извлеките из него IFoo и используйте его в других интерфейсах:

public interface IMyService
{
    public IBar DoStuff(IFoo foo);
}

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

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

Если Foo выглядит так

public class Foo
{
    public Baz Baz { get; }
}

, интерфейс должен выглядеть так:

public interface IFoo
{
    IBaz Baz { get; }
}

public interface IBaz {}

(извиняюсь за код C #, если вы пишете на другом языке ...)

{{1 }}
1
ответ дан 5 December 2019 в 21:18
поделиться

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

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

Но это действительно во многом зависит от того, какие типы вы собираетесь открывать и кому. Не могли бы вы привести несколько примеров?

2
ответ дан 5 December 2019 в 21:18
поделиться

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

Если GeneratePdfFromTiff просто рассматривает DocumentInfo как объект параметра и класс информации о документе не имеет никакой логики, он должен быть просто общедоступным типом.

Если класс информации о документе выполняет вычисления или делает что-то еще интересное, то определенно стоит извлечь интерфейс. (По всем тем замечательным причинам, которые Марк упоминает в своем ответе)

.
1
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

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