Правильное разделение ответственности

Вурдалак

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вурдалак, ты повторяешься, я уже отвечал
 

skwee

Новичок
Мысли в слух:
Для каждого энтити держим флаг isDirty, так как репоситори держит ссылки на все энтити, можно делать так
PHP:
class PostRepository{
  private $_posts = array();
  public function store() {
    foreach($this->_posts as $post) {
      if($post->isDirty()) {
        $this->_storeImpl($post);
      }
    }

    public function findByPrimaryKey($key) {
        if(array_key_exists($key, $this->_posts) return $this->_posts[$key];
        $this->_posts[$key] = $this->_loadImpl($key);
        return $this->_posts[$key];
    }
  }
}
=========
class PostEntity {
  private $_isDirty = false;

  public function setTitle($title) {
    ...
    $this->_isDirty = true;
  }
}
и тогда не надо делать в энтити методы вроде
PHP:
class UserEntity {
  public function getPosts() {
    return $this->_posts;
  }
}
=======
class UserRepository {
  public function store(UserEntity $user) {
    $posts = $user->getPosts();
    $postRepo = new PostsRepository();
    $postRepo->storeMany($posts);
    if($user->wasModified()) {
      $this->_storeImpl($user);
    }
  }
}
тем самым не нарушая
Aggregate: A collection of objects that are bound together by a root entity, otherwise known as an aggregate root. The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
а референсы будет держать токо репоситори
 

skwee

Новичок
Мысли в слух:
Контроллер пользуется слоем валидации для проверки данных, если данные валидны он посылает их в нужный акшен.

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

==Edit==
Репозиторий не всегда должен быть 1:1 с БД. Пример:
UserEntity и ActivationCodeValueObject
ни что не мешаеть сделать две таблицы в БД: Users, ActivationCode но репозиторий будет один UserRepository который будеть делать join чтобы вернуть UserEntity с ActivationCodeValueObject.
ИМХО это очень правильно. Сам маялся как сделать пока не осознал что репозиторий это не 1:1 mirror таблиц в БД а всего лиш хранилище данных. А как эти данные хранатся в одной или в 10 таблицах, ему пофиг он просто должен знать как из этих данных вернуть полноценный энтити.

==Edit==
Проектируя систему ДДД не думайте в понятиях базы данных! Это не првильно. Пример:
Логично что Identity User-а это ID из БД, но потом я подумал как реализовать User::factory(...) он не создает запись в БД, а просто делает new User(..); но у каждого энтити должен быт Identity, а как мне знать АйДи если я не пишу в БД?! Так вот дорогие мои, Identity User-а это не АйДи из БД, а email в моем случаее, АйДи в БД это просто для удобства связи и быстрого поиска. Вот так вот.
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
Проектируя систему ДДД не думайте в понятиях базы данных! Это не првильно. Пример:
Логично что Identity User-а это ID из БД, но потом я подумал как реализовать User::factory(...) он не создает запись в БД, а просто делает new User(..); но у каждого энтити должен быт Identity, а как мне знать АйДи если я не пишу в БД?! Так вот дорогие мои, Identity User-а это не АйДи из БД, а email в моем случаее, АйДи в БД это просто для удобства связи и быстрого поиска. Вот так вот.
По-моему как раз наоборот. Юзер должен оставаться тем же юзером даже после смены емейла. Как раз id и делает его сущностью, обеспечивает его продолжительность существования независимо от атрибутов.
А насчет фабрики - я думаю, что просто до записи в репозиторий, User не является полноценной сущностью - это скорее valueobject, эмбрион, который после прописки в базе получает сущность. Это как бомж - пока у него нет паспорта, государству все равно с каким именно бомжом оно имеет дело.
 

skwee

Новичок
varan
Интерестный подход. Но бизнес модель не должна зависить от реализации хранилеща (тут хранилеща != repository в ДДД, а SQL storage или noSql storage или memory storage или file storage и тд). Если завтра ты поменяеш mysql на mongodb или xml файлы твоя модел не должна менятся.

Юзер должен оставаться тем же юзером даже после смены емейла.
А что ему мешает остатся тем же юзером?
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
varan
Если завтра ты поменяеш mysql на mongodb или xml файлы твоя модел не должна менятся.
Если юзер - это вещь в себе, и никак не привязан к остальным элементам модели, то тогда ему не нужен id, Если же по юзеру будет вестись статистика или он будет привязан к еще к 100500 объектам, emailом тут не обойдешься - и в том же xml или mongo будешь хранить его id. Независимо от реализации хранилища.

Получается, что id юзера - часть модели
 

AmdY

Пью пиво
Команда форума
varan
самое ужасное, что от базовской id с автоинкрементом затем приходишь к uid, чтобы работать на распределённых стораджах.
 
Сверху