Я это считаю вообще неправильным и вредным. Зачем сначала строить агрегат в память и потом целиком его сохранять? Можно ведь и кусочками в транзакции:
Код: Выделить всё
class AggregateRoot extends ActiveRecord
{
public function changeRootAndRelationsSimultaneously(array $attributes, array $related_attributes): void
{
$this->scenario = self::COOL_SCENARIO;
$this->setAttribures($attributes);
self::getDb()->transaction(function () {
if (!$this->save()) {
if ($this->hasErrors()) {
$error = array_values($this->getFirstErrors())[0];
} else {
$error = 'Unknown error';
}
throw new DomainException($error);
}
$this->unlinkAll('relation_name', true);
foreach ($related_attributes as $item) {
$related_model = new RelatedModel([
'foreign_key' => $this->id
]);
$related->create($item);
}
});
}
}
class RelatedModel extends ActiveRecord
{
public
function create(array $attrs): void
{
$this->scenario = self::COOL_SCENARIO;
$this->setAttributes($attrs);
if (!$this->save()) {
if ($this->hasErrors()) {
$error = array_values($this->getFirstErrors())[0];
} else {
$error = 'Unknown error';
}
throw new DomainException($error);
}
}
}
А я думаю наоборот. Yii как раз лучше к Agile подходит, чем DDD. Когда agile меняться может все, от данных до фронтенда. Так как нет абстрактного домена, то кода меньше, меняется быстрее.
Да, тут понаписали много смешных вещей про "архитектуру". Я сам иногда досадую, что велся на это.
Всю эту критику можно кратко описать так:
1. Вася писал на Yii и все было ok, проекты пилились.
2. Вася прочитал книгу/статью по DDD, красивые примерчики доставили. И там было написано слово enterprise. Захотел также.
3. Вася попробовал делать на Yii как пишут в DDD/SOLID-книгах.
4. Не получилось также кошерно, как в примере в книге, вывод Yii неправильный фреймворк, и все кто его используют ошибаются. Вася идет критиковать на форум.
Подходы к Yii есть, код можно сделать хороший. Да и по мне код написанный до моды на DDD вызывает реально меньше негативных эмоций и как правило рефакторится легче.
Я SL юзаю посредством Instance::ensure() в методах Component::init() в том числе и в AR.
У SL две проблемы - зависимость от него и недоступность сервисов в разных контекстах (web, console).
Про первую можно вообще забыть если не пишешь библиотеку.
Второе лечится быстрым заваливанием в случае отсутствия возможности получения отдельного сервиса в конструкторах или init(), обнаруживается и фиксится быстро, особенно если есть тесты.
В остальном одни плюсы. Особенно в SL доставляет, что если есть класс A порождающий B порождающий C порождающий D, а D зависит от X, то зависимость X не нужно прокидывать начиная с A, D может получить его сам. Тестится норм, синглтоны мокаются, нужные сервисы в $app подкладываются.