На чём лучше прокачивать архитектурный навык разработки моделей предметной области и принципов DDD вообще?
============================================================================================================

 Лично для себя пишу тестовое приложение для повышения архитектурного навыка и практик работы с автоматизацией окружения.  

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

Приложение типа SPA, Angular 2 на фронте.  

Сервер планируется в качестве API, возможно REST.  

Мне казалось, что я достаточно хорошо разобрался в теме архитектуры ООП приложений, но на последнем этапе, уже установив фреймворк, подняв виртуалку с окружением, установив ларавель, начал читать "залпом" существующие статьи про архитектурные подходы, и, надо сказать, совершенно перемешал те знания и семантические связи, которые имел касательно архитектуры. Да и читая мнение разных людей, прихожу к выводу, что нет единого мнения и (или) понимания. Одни споры и разговоры об одном, но по разному. По сути, даже единого согласия о DDD не увидел, каждый как то сам себе его понимает...  
  

Как то не обратил внимания, что родная работа с данными в Laravel ведется с Active Record. С ним я хорошо знаком в Yii, да и с нуля сам реализовывал в своём мини-фреймворке. Понимаю, что это антипаттерн в плане того же принципа единой ответственности. Хотелось поработать более плотно с DataMappers и вообще с новой ORM - Doctrine 2, к : пока писал примеру. И тут на тебе - читаю, что дата-мапперы в контексте stateless - антипаттерн а Doctrine - вообще мало совместим с пхп - это из статьи на хабре. Т.е. REST не совмещается уже.   

Планировал перейти от Data к Domain Driven Development - опять же в целях обучения. Как это реализуется на Laravel? Или может мне с такими запросами и не он нужен? Начинаю приходить к мнению, что выбор в сторону ларавель - не более чем недостаточная информированность, т.к. читая о симфони кажется, что на нём будет лучше оттачивать практики хороших абстракций и разработки моделей предметной области.  
  

Кроме того, установленный ларавель с его фасадами фасадами как то не сильно сдружился с PHPStorm. Да и начиная с фронт-контроллера нет никакой возможности перемещаться по классам и изучать фреймворк (как в Yii, к примеру). Вроде, это как то решается какой-то доустановкой, которая продокументирует код, но пока не смог реализовать.  
  

Не стоит писать что-то абстрактное типа "всё зависит от проекта", "архитектура не привязана к фреймворку" ... Очень даже привязана. А философствовать на тему архитектуры ПО я, как и еще многие, могу часами и днями. Но когда доходит дело до разделения обязанности между компонентами и реального моделирования... Внезапно всё не так однозначно. 

 Любой фреймворк с инверсией зависимостей подойдет. На Symfony и Yii2 точно можно сделать. На русскоязычном форуме Yii по теме DDD [очень много обсуждений](http://www.yiiframework.ru/forum/viewforum.php?f=34&sid=cd71aa2ac3b3ababbc5b8e220d93aa9e). Но если не увидели единого согласия по DDD, то скорее всего не читали книгу Эванса или Вернона. Если так, то лучше начать с кого-нибудь из них.  
  

Многоуровневая архитектура рассказывает нам о слоях presentation, application, domain и infrastructure. С однонаправленным потоком данных. Нижестоящий слой, никогда не должен вызывать вышестоящий. Это значит, что к примеру можно выбросить presentation слой и не придется ничего изменять в оставшихся 3.  
  

Фактически выходит, что в любой момент можно выбросить фреймворк и заменить другим, так как это presentation layer в многоуровневой архитектуре. Можно даже сначала написать application/domain, проверить их юнит-тестами, а только потом уже задуматься о фреймворке. Application/domain слои никогда ни при каких обстоятельствах не должны вызывать методы фреймворка. Контроллеры фреймворка работают с доменной моделью, через вызовы методов application layer.  
  

Соответственно, при миграции на другой фреймворк, всё что потребуется, это переписать контроллеры (методы очень простые 1-5 строк) и реализации классов в infrastructure layer если вы завязывали их на фреймворк. Хотя лично я бы, не советовал этого делать. Лучше найти/написать отдельные библиотеки/компоненты под инфраструктурный слой, тем самым облегчив себе жизнь в будущем, когда фреймворк умрет или при очередном релизе мажорной версии.  
  

Symfony под DDD наилучший выбор, он компонентный, можно подтянуть только то, что нужно. С другой стороны Yii2, он монолитный и вы затяните Active Record и кучу всего еще, чем не будете пользоваться, но джуниор придет и обязательно понавызывает AR или чего-нибудь еще в application/domain слоях, чего вы явно не ожидаете. Поэтому в случае с Yii2 нужен будет тотальный контроль. :)  
  

Про Laravel не пишу ничего, так как не работал с ним. Но судя по беглому просмотру документации, никаких проблем сделать на нем DDD также нет. 

 Посмотрите записи вебинаров Дмитрия Елисеева, "Интенсив ООП" - очень рекомендую   

[www.elisdn.ru/oop-week](http://www.elisdn.ru/oop-week) 

 Doctrine 2 очень даже хороший инструмент.  
  

Я бы вам порекомендовал использовать фреймворк Symfony 3. На PhpStorm поставить плагин Symfony plugin и PHP annotations. 

 Напишу то что вы происили не писать.   
  

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

В вашем же вопросе намешано все вместе. 

> Как это реализуется на Laravel? Или может мне с такими запросами и не он нужен?

  

Никак не реализуется  
  

> Кроме того, установленный ларавель с его фасадами фасадами как то не сильно сдружился с PHPStorm.

  

Для этого существует плагин [Laravel IDE helper](https://github.com/barryvdh/laravel-ide-helper).  
  

DDD - просто подход к конструированию архитектуры приложения, его можно реализовать с помощью любого фреймворка.  

Другое дело что некоторые фреймворки/библиотеки могут существенно упростить применение такого подхода.  
  

Чтобы полноценно работать по DDD, Вам необходимо как можно больше абстрагироваться от кода, ответственного за техническую часть (работа с БД и прочее). В этом как раз помогут паттерны Repository, UnitOfWork, DataMapper и т.д.  
  

Эти шаблоны уже реализованы, например, в ORM Doctrine. В Laravel же по-умолчанию в качестве слоя БД используется ActiveRecord, который применяется преимущественно в целях RAD (rapid application development).  
  

Если очень хочется Laravel, можете попробовать [AnalogueORM](https://github.com/analogueorm/analogue). Это DataMapper-надстройка над Eloquent. Все остальное придется реализовывать ручками.  
  

Поэтому если хотите начать работать полноценно и сразу, берите Doctrine 2 (либо Hibernate для Java, либо SQLAlchemy для Python и т.д.) и что-то в придачу к нему (тот-же Symfony или любой другой веб-фреймворк с инверсией контроля).  
  

Если же хотите поразбираться каким образом все устроено на техническом уровне, берите AnalogueORM или нечто подобное и пробуйте остальное реализовывать вручную. 

 Реализовывал принципы DDD на разных технологиях от Yii-1 до ASP.NET.  

Тут главное уметь разделять нужную логику в нужный слой. Иногда нужно отступить от мануала вашего фреймворка и дописать свой велосипед. Но потом это окупается.   
  

По Data Access Layer могу сказать, что нужно использовать паттерн Repository. В качестве основной реализации использовать родную для фреймворка ORM, затем всё равно так или иначе будете отказываться от ORM и писать более низкоуровневые запросы.  
  

По фреймворку - Lumen. Это Laravel для stateless REST API.   
  

О том как лучше понимать DDD. Кроме классических книг по этому вопросу могу посоветовать в поиске github ввести DDD или domain driven design. Там множество разных примеров на разных технологиях. 

 Как упоминают авторы других ответов, очень важно разделять задачу на части со сфокусированными зонами ответственности. Важно держать под контролем их взаимопроникновение, определять, кто от кого должен зависеть, а кто нет. И каким образом всё это можно согласовать с необходимыми характеристиками разрабатываемой системы. Иначе говоря, древний принцип "Разделяй и властвуй" и его IT-интерпретация "Single Responsibility Principle" - наше всё.  
  

В частности, решая задачу, вписывающуюся в область применения DDD, мы должны выделить ядро, которое моделирует определённый ограниченный контекст. Вероятнее всего, также мы должны подумать о разделении обработки команд и запросов. Потому что команды означают изменение состояния предметной области, всякие валидации, транзакции, консистентность и прочее. Запросы же означают иное представление данных, эффективный доступ на чтение, инвалидацию кешей и т.д., и т.п.  
  

Так от чего же должно зависеть DDD-ядро? Должно ли оно зависеть от конкретной реализации БД или ORM? От того, какие таблицы присутствуют в Вашей реляционной СУБД?  

 Или от протокола HTTP? Или, допустим, от конкретной файловой системы? Эти вопросы являются скорее риторическими. Поиск ответов на эти вопросы, а также подхода к тестированию DDD-ядра привели к описанию Hexagonal Architecture (известной также под именем Ports And Adapters). Очень советую узнать подробности и поискать, как Вы могли бы сделать такое доступными Вам средствами PHP.  
  

Пара других наводящих вопросов: должна ли работа с HTTP как-либо быть связана с взаимодействием с БД? Какой из компонентов системы должен знать параметры подключения к БД? Должны ли совпадать жизненные циклы ответа на HTTP-запрос и агрегатов в DDD-ядре? Должен ли HTTP-фреймворк диктовать Вам организацию DDD-ядра? Должен ли ORM-фреймворк диктовать Вам организацию DDD-ядра? А кто всё-таки должен?  
  

Буду ждать Ваших комментариев.