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

Должны ли объекты домена отображаться как интерфейсы или как обычные объекты?

Должны ли объекты домена отображаться как интерфейсы или как обычные объекты?

Пользовательский интерфейс:

public interface IUser
{
    string FirstName { get; set; }
    string LastName { get; set; }
    string Email { get; set; }
    Role Role { get; set; }
}

Пользовательская реализация (реализована в LinqToSql Data Access Layer):

public class User : IUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Role Role { get; set; }
}

Пользовательская реализация (внедрена в уровень доступа к данным NHibernate):

[NHibernate.Mapping.Attributes.Class]
public class User : IUser
{
    [NHibernate.Mapping.Attributes.Property]
    public string FirstName { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public string LastName { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public string Email { get; set; }

    [NHibernate.Mapping.Attributes.Property]
    public Role Role { get; set; }
}

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

4b9b3361

Ответ 1

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

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

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

Доступ к данным - это общая область, где вам нужны лучшие абстракции (недержание невежества). В вашем примере у вас есть атрибуты NHibernate в вашем классе модели. Но добавление атрибутов persistence делает его уже не истинным классом домена, потому что он вводит зависимость от NHibernate. NHibernate и Fluent NHibernate поддерживают сопоставление POCOs с использованием объявления внешнего сопоставления вместо атрибутов в классе данных, и это, как правило, является предпочтительным подходом при использовании ORM, таких как NHibernate или EF4, поскольку это нарушает зависимость между моделью устойчивости и моделью домена.

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

Некоторые типы объектов, которые вы хотели бы выставить в качестве интерфейсов:

  • Хранилища, которые отвечают за загрузку/сохранение объектов домена;
  • Плагины/расширения для вашей программы;
  • Модели просмотра/презентатора, чтобы можно было подключить различные интерфейсные интерфейсы;
  • Абстрактные типы данных со многими реализациями (массив, список, словарь, набор записей и таблица данных - это все последовательности AKA IEnumerable);
  • Абстрактные операции со многими возможными алгоритмами (сортировка, поиск, сравнение);
  • Коммуникационные модели (такие же операции над TCP/IP, именованные каналы, RS-232);
  • Все, что зависит от платформы, если вы планируете развертывать более одного (Mac/Windows/* nix).

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

  • Зависит от факторов, которые, вероятно, выходят за рамки вашего контроля;
  • Скорее всего, это изменится в будущем; и
  • Горизонтальные функции (используемые во многих частях приложения/архитектуры).

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

Ответ 2

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

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

Ответ 3

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

В вашем примере интерфейса нет никакого поведения за пределами getter/setter. Для этого не нужны интерфейсы.

Ответ 4

В большинстве случаев сущность не должна вводиться.

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

Например: скажем, что у вас есть Customer, и вы реализуете Customer как AmericanCustomer. Дайте ему все поведение и состояние, необходимые для того, чтобы быть американским клиентом (подсказка: любит ходить по магазинам!). Затем позже тот же Customer, с тем же именем, одинаковые привычки покупок - отправляется в Японию. Являются ли они еще AmericanCustomer? Создаете ли вы новый JapaneseCustomer и скопируете все эти данные, включая идентификатор этого клиента, в этот новый тип? Это может иметь последствия.

Разве тот же клиент все еще любит ходить по магазинам? Это может быть или не быть правдой для JapaneseCustomer. Но теперь в одном забронированном полете этот Customer отличается. Другие объекты в системе будут запрашивать тот же Customer, используя свой уникальный идентификатор, и могут закончиться с другим изображением объекта, чем они ожидали (a AmericanCustomer). Возможно, заказчик моделируется вокруг национального происхождения вместо текущего местоположения. Это может решить некоторые проблемы, но и ввести новые.

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