Pull to refresh

Comments 15

О, гексагоналка! Начало уже интригующее и выглядит как годный материал, наконец-то)

У меня следующий вопрос остался.

Правильно ли я понимаю, что это НЕ классический вариант с

  • App\Example\{Domain, Application, Infrastructure, Presentation} + App\Some\{Domain, ...etc}, а в обратную сторону:

  • App\Domain\Example + App\Infrastructure\Example + ... + App\Domain\Some + ...etc (иначе зачем Shared)? Или предполагается что контекст/предметная область/домен у нас один единственный на данный момент?

Вопрос вот к чему: Известно что один домен не может лазать в другой и наоборот. Это считай что разные приложения должны быть, которые можно в будущем разнести вообще на разные сервисы.

Так что интересно как будет решена проблема с VO, которые пересекаются между разными доменами. Ну например, есть у нас App\Domain\Car\... внутри которого всякие доменные сервисы, энтити и прочая шалупонь. Есть VO App\Domain\Car\Name + его сервисы App\Domain\Car\Name\NameParser (например).

Потом добавляется статистика и какие-нибудь события: App\Domain\Statistics\Event\CarHasBeenDestroyed, которые в свою очередь могут дёргать App\Shared\Domain\CarId (потому что шаред), но не могут дёрнуть Name, т.к. это другой домен. Предполагается двигать Name тоже в Shared? Но это всё же VO не общее, а принадлежащее исключительно машинам (домену Car). Что в таких случаях предполагается делать?

P.S. А в чём была причина отказываться от Presentation слоя, куда складываются хттп контроллеры, консольные команды, реквест/респонз дто и проч.? Ради упрощения (я так понимаю вы его с Application объеденили) и дабы не оверинженерить лишние слои?

P.P.S. Вместо *.sh скриптов можно использовать composer ;)
Просто туда добавить эту простыню из команды и повесить алиас, чтоб можно было вызывать как composer deptrac и всё: https://getcomposer.org/doc/articles/scripts.md

В папке Domain и других лежат "модули". То есть у нас как бы одно единственное приложение, которое не разделено на структуры типа Car\{App, Domain и Infrastrucutre}, а наоборот - все объединено в App, Domain и Infrastrucutre и имеет внутри то, с чем работаем. Данный подход на текущем этапе достаточен.

По поводу работы VO "разных доменов" тут получается так, что мы можем можем использовать в рамках Car все, что внутри, если нам надо использовать в Racer что-то из VO Car, то для этого формируется VO на стороне Racer, который на инфраструктурном слое парсится из CarVO -> RacerCarVO. Другой подход - прямое использование, так как по факту приложение одно и "область видимости" тоже. Вот если бы были разные структуры (описал выше), то тогда да, маппинг через anticorruption layer или что-то в таком духе.

 В чём была причина отказываться от Presentation слоя

Никто не отказывался, мы просто пока не дошли до этого момента. Я же пишу в формате "живого блога". Поэтому, когда мы дойдем до запросов (а это вообще последнее, что будет), то добавим нужные слои. Но, на самом деле, это вообще не важно, так как мы будем писать команды, которые по факту будут вызываться в Presentation слое.

Вместо *.sh скриптов можно использовать composer

Дельное замечание, забыл про это совсем. Подумаю над переносом в composer.

если нам надо использовать в Racer что-то из VO Car, то для этого формируется VO на стороне Racer, который на инфраструктурном слое парсится из CarVO -> RacerCarVO. Другой подход - прямое использование, так как по факту приложение одно и "область видимости" тоже.

Понял, если разные домены, то предлагается копипастить. Благо DTO и не критично. А что делать в таком случае с сервисами, относящимися к этому VO? Ну там парсеры, валидаторы, ещё мб что?

Например, также берем anticorruption layer и связываем все что хотим. Просто если мы были бы разными командами разработки, то напрямую ничего вашего трогать не могу. Тут цельная структура об одном и том же (контекст), так что можно использовать без проблем.

С другой стороны, никто не мешает написать адаптеры на anticorruption layer, чтобы "законно" использовать что-то "чужое"

Ну вот да, я тоже об этом. Что если мы совсем в разных отделах сидим, то трогать не получится. А копипаста уж очень избыточна.

С другой стороны, никто не мешает написать адаптеры на anticorruption layer, чтобы "законно" использовать что-то "чужое"

Хм, не совсем понимаю. Предполагается что эти адаптеры потом просто в шаред сложить? Или каким образом? Допустим у нас разные команды (т.е. не ваш вариант из статьи, а тот что предположили в комментариях), вот в таком случае:

- Car\
  - Domain\
    - SomeCarVO
    - SomeCarVO\
        - SomeCarVOParser
        - SomeCarVOValidator
        - SomeCarVOCreator
- Racer\
  - Domain\
    - ... и тут очень хочется взять VO + сервисы SomeCarVO что запрещено

И кроме как скопипастить этот VO, а общение с его сервисами настроить через CommandBus/QueryBus у меня идей не возникло, да и статей особо не нашёл (плохо гуглил возможно).

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

Хм, т.е. нейминг "Adapter" (ну и предметная область соответственно) фактически "легализует" доступ до сторонних доменов если я правильно понял?

Есть шаблон проектирования "Адаптер" посмотри.

Лет 10 назад я такое уже писал. Правда не только для парных заездов. Но не взлетело. Надеюсь у вас взлетит

Если поделитесь опытом, то будет очень кстати. Проект реализуется от простого к сложному, потом будет и квалификация и прочее. Пока решил сделать так, чтобы не захламлять мозг и не путаться от масштаба.

Какая разница в каких папках лежат какие файлы?

Разница в архитектуре приложения, связанности классов, разделения логики. Например, вы обедаете на кухне, а спите в спальне. По хорошему, вы не должны обедать в спальне. Вот и такая история тут.

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

Прозвучит неожиданно, но избавившись от папок (просто кладя всё в "src") можно избавиться от головной боли по организации того, что организовать невозможно.

Что же, это ваш выбор, но уйма ООП приложений PHP работают именно по какой-то архитектуре директорий, символизирующие не только слои приложения, но и namespace.

Один "файл" может логически относиться к более чем одной "папке"

Можно пример? Желательно в рамках предложенной структуры, но если не получится, то тогда свой.

Sign up to leave a comment.

Articles