Дизайн уровня доступа к данным в DDD - PullRequest
4 голосов
/ 09 сентября 2011

Извините за мой плохой английский.

Хорошо, сейчас я думаю о подходе DDD, и это звучит замечательно, но ... Есть один маленький вопрос по этому поводу. DDD говорит, что уровень модели домена полностью отделен от уровня доступа к данным (и всех других уровней). Поэтому, когда DAL сохранит какой-либо бизнес-объект, он будет иметь доступ только к открытым свойствам этого объекта. Теперь вопрос:

Как мы можем гарантировать (в целом), что набор открытых данных объекта это все, что нам нужно, чтобы восстановить объект позже?

Пример

У нас есть следующие бизнес-правила:

  1. Для создания бизнес-объекта должны быть указаны пользователь и домен.
  2. Пользователь и домен не могут быть изменены после создания объекта.
  3. Бизнес-объект имеет свойство Email, которое выглядит как «user @ domain».

Вот чистое POCO, описывающее эти правила:

public class BusinessObject
{
    private string _user;
    private string _domain;

    public BusinessObject(string user, string domain)
    {
        _user = user;
        _domain = domain;
    }

    public string Email
    {
        get { return _user + "@" + _domain; }
    }
}

Таким образом, в какой-то момент DAL сохранит этот объект во внешнем хранилище (то есть в базе данных SQL). Очевидно, DAL сохранит свойство «Email» в соответствующем поле в БД. Все будет прекрасно работать до того момента, пока мы не попросим DAL восстановить объект. Как DAL может это сделать? Объект должен иметь открытый установщик как минимум для поля «Электронная почта». Что-то вроде

public string Email
{
    set
    {
        string[] s = value.Split("@");
        _user = s[0];
        _domain = s[1];
    }
}

На самом деле, объект будет иметь открытые методы получения / установки для полей «Пользователь» и «Домен» и метод GetEmail (). Но остановись. Я не хочу, чтобы у моего POCO была такая функциональность! Для этого нет бизнес-правил. Это необходимо сделать для возможности сохранения / восстановления только объекта.

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

Единственный обходной путь, который я вижу, - это иметь какой-нибудь инструмент системного уровня, который может создать дамп объекта для нас и может восстановить объект из этого дампа в любое время. И DAL должен поместить этот дамп в хранилище в дополнение к публичным свойствам объекта. Поэтому, когда DAL необходимо восстановить объект из хранилища, он использует для этого дамп. А открытые свойства, сохраненные в хранилище, можно использовать, когда DAL выполняет операции, для которых не требуется создавать экземпляр объекта (т. Е. Большинство запросов link2sql).

Я делаю это неправильно? Мне нужно больше читать? О некоторых моделях, может быть, ORM?

Ответы [ 2 ]

5 голосов
/ 09 сентября 2011

Я думаю, вы ошиблись этой частью:

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

Модель домена не зависит от DAL.И наоборот, DAL зависит от модели домена.ORM обладает глубокими знаниями об объектах домена, включая частные поля.В этом нет абсолютно ничего плохого.На самом деле это лучший способ реализовать постоянное невежество в DDD.Вот так может выглядеть класс Domain.Обратите внимание, что

  • поля могут быть закрытыми и доступны только для чтения.
  • public Constructor используется только клиентским кодом, а не DAL.
  • нет необходимости в методах получения и установки свойств
  • Бизнес-объект почти на 100% не знает о проблемах с постоянством

Единственное, что нужно DAL / ORM - это частный константор без параметров:

public class BusinessObject {
    private readonly string _user;
    private readonly string _domain;

    private BusinessObject(){}

    public BusinessObject(string user, string domain) {
        _user = user;
        _domain = domain;
    }

    public string Email {
        get { return _user + "@" + _domain; }
    }
}

И магия происходит вОРМ.Hibernate может восстановить этот объект из базы данных, используя этот файл сопоставления:

<class name="BusinessObject" table="BusinessObjects">
    ...
    <property name="_user" column="User" />
    <property name="_domain" column="Domain" />
    ...
</class>

Другим аспектом постоянного невежественного кода домена является Репозиторий DDD :

Определение:Репозиторий - это механизм для инкапсуляции хранения, извлечения и поиска, который эмулирует коллекцию объектов.

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

1 голос
/ 09 сентября 2011
public class BusinessObject
{
    private string _user;
    private string _domain;

   public BusinessObject(string email)
   {
      string[] s = value.Split("@");
      _user = s[0];
      _domain = s[1];    
   } 

   public BusinessObject(string user, string domain)
    {
        _user = user;
        _domain = domain;
    }

    public string Email
    {
        get { return _user + "@" + _domain; }
    }
}

Одно простое решение - просто позвонить по DAL новый BusinessObject (электронная почта)

...