В общем... Как понял из хейта, если я в Yii использую встроенный ActiveRecord, то я просто обязан везде лепить "как все":
if (!$user = User::findOne(['email' => $email])) {
throw new NotFoundException(...);
}
$user->status = User::STATUS_ACTIVE;
if (!$user->save()) {
throw new RuntimeException(...);
}
и мне нельзя в AR добавить ООП, подключить плагин для связей и инкапсулировать вызов поиска и сохранения в какой-нибудь объект Repository, чтоб всю лапшу сменить на код:
$user = $this->users->getByEmail($email);
$user->activate();
$this->users->save($user);
потому что это "не persistance ignorance и не framework agnostic" и "вдруг в проект придёт джун и обкакается". Да и вообще потому, что так никак нельзя делать в AR или чём то ещё и можно лишь в их православном DM. И готовы бить морду за то что "нет контекстов, значит код говно" :)
Если так, то, видимо, у многих DDD-анутых оппонентов отсутствует не-DM мозг.
Ну и не читают диагональщики разборов вроде http://www.elisdn.ru/blog/104/domain-entities-modelling про репозитории, где мы рисуем агрегаты и сохраняем их в DM, Doctrine и ActiveRecord. С коллекциями, прокси, феншуем и костылями.
Такс по пунктам:
1. Никто нигде ничего не обязан. Делайте как вам удобно, но не вводите людей в заблуждение что это SOLID, DDD или что-то еще.
2. "мне нельзя в AR добавить ООП" ну тут я даже не знаю как комментировать...
3. "что так никак нельзя делать в AR или чём то ещё и можно лишь в их православном DM" внезапно PI никоим образом не говорит использовать DM или что-то еще, будь то AR, R(TD)G и иже с ними. Просто ваш репозиторий не несет никакой пользы. Он ничего не инкапсулирует "от слова совсем" (с) Максим. PI поверх AR пилится вполне себе легко и доступно. Собсно сам так жил с Propel лет так 5 назад. Достаточно:
a) Выделить интерфейс репозитория и положить его рядом с доменной моделью. А уже в Yii будет лежать имплементация аля ActiveRecordUserRepository.
б) Разделить доменную модель и AR модель и гидрировать доменную из AR (и наоборот) в том же репозитории. Для примера ваш UserRepository::findByEmail() будет выглядеть как-то так:
`
function findByEmail(string $email): Shop\User
{
// В AR классах оставляем всю yii муть
$userRecord = UserRecord::getByEmail($email);
$user = new Shop\User($userRecord->name, $userRecord->email, ...);
$this->uow->registerClean($user); // Если мы не хотим вызывать явно UserRepository::save();
return $user;
}
3. "И готовы бить морду за то что "нет контекстов, значит код говно": дело не в том что их нет, дело в том когда они должны появится. И вроде вы на это уже ответили. Зачем возвращаться?
4. "Ну и не читают диагональщики ..." кто и что читает личное дело каждого. Поверьте ничего нового вы мне не открыли. ЗЫ. В статье годно вполне расписано все.