Pull to refresh
18
17
Александр Братко @abratko

Прагматик, fullstack senior developer

Send message

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

  1. я не думаю о домене как слое внутри слоя приложения. Здесь граница сильно размыта. Эта часть сама проявится, когда будут четко выстроены границы слоев. Для меня домен - это ограниченный контекст, далее я буду использовать его именно так.

  2. я знаю, что есть 4 слоя: приложение, инфраструктура, контроллеры и конфигурация. Приложение и конфигурация могут отсутствовать.

  3. я знаю, что приложение это главный слой, все "подстраиваются" под него, кроме конфигурации. Конфигурация - это композиция компонент.

  4. я знаю, что есть вертикальные зависимости между слоями (внутренние зависимости домена) и горизонтальные, внутри слоя между разными доменами (внешние зависимости домена). Слои и домены образуют "решетку".

  5. я осознанно сильно связываю вертикальные (внутренние) зависимости между слоями внутри домена и делаю конструкцияю прочной по вертикали. В вертикале я не использую абстракции, если возможно. Это противоречит DIP, но сильно уменьшает когнитивную сложность. Это связано с тем, что вероятность вертикальных изменний мала без изменения слоя приложения.

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

  7. я знаю, что есть поток данных. Он движется вертикально по слоям внутри домена в двух направлениях: сверху - вниз и обратно. Зная, что слой приложения главный и понимая какой поток обрабатывает текущий код, я понимаю, куда ставить мапперы и фабрики. Их позиция может меняться в зависимости от задачи, но у меня всегда есть ответ на вопрос - почему они здесь.

Очень малелький пример конфигурации такого подхода описан здесь с статье "Еще раз про Di-контейнеры в golang" раздел "Применяем в реальном проекте"

Это не так. Мапперы, которые отвечают за преобразование данных при переходе между слоями, должны быть в точно определённых местах нижних уровнях. Если у вас это не так, скорее все у вас нарушение зависимости слоев.

Здесь вопрос в другом - где лежат мапперы и, главное, почему?

Это важно. Если они лежатт не там где надо, то в других местах тоже возникнут проблемы.

Есть что обсудить, например. Компоненты слоя APPLICATION

Mappers – это вспомогательные компоненты, которые преобразуют Entity в DTO и обратно.

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

Вопрос: почему маппер, который лежит в слое приложения, должен знать структуру DTO, которая определяется "нижним" слоем инфраструктуры? Или я что-то не понял?

Допустим, это речь о DTO слоя приложения, и он не совпадает в DTO слоя инфраструктуры. Это нормальная ситуация. Тогда в слое инфраструктуры должен быть маппер DTO приложения на DTO инфраструктуры, но у Вас этого нет в описании слоя инфраструктуры.

Какая-то нестыковочка получается.

так... непорядок. Смотрю сюда.

Сравнение терминологии слоёв и компонентов архитектур

Сущности есть, объекты-значения есть. Где агрегаты? Агрегаты, которые отвечают за транзакционную целостность и согласованность всех сущностей и объектов-значений внутри себя. Где они, родимые?

орфографие или фактологией поработать надо.

нет, автору из минусов это не понять. Там нет конкретики.
А читатель видит + - и всё, больше ничего. Тоже ничего не понятно.

С современном мире много способов отображения реакций.
Читателям важна скость и беглось.
Хотите реагировать эмоционально, хорошо. Пусть это будет эмодзи.
Вопросы по существу? Ок, минусуйте, но с комментом.

Короче, вариантов масса. А Хабр как-то застрял, на мой взгляд.

ну так в этом и смысл.

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

Хабр как-то застрял в начале 2000-х.

А можно еще вот так

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

не сильно отличается от

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

но результат абсолютно разный

Цель не получить плюс, а получить обратную связь. Для плюсов какая обратная связь? Если плюс то, согласен.

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

все объяснительную на 1200 слов писали, чтобы минус лепить?

можно и меньше, но - да, хочу.

тебе приятнее будет?

Нет. Дело не в плюсах. Статья не про плюсы, а про развитие и конструктиную обратную связь. Здесь https://habr.com/ru/articles/904864/comments/#comment_28227696 уже обратили внимание на то, что я мазахист. Мне нужна критика.

Ну...так об этом и речь. Минусовать можно без комментариев. Хочется, если минус, то коммент обязателен.

Ну, нет... =)
Ситуация как в анекдоте.

Встретились мазахист и садист.
Мазахист: "Ну, бей меня, бей!!!"
Садист: "А...!!! Не буду!!!"

Мне минуса мало.

Опять мимо. Я не против, что бы меня минусовали не только "мальчики', но и "девочки". Но только, что бы они дополнительно оставляли коммент, что бы нельзя было просто так минусовать.

Что бы всем было хорошо.

Какие правила я предлагаю менять? Где это описано в статье, конкретно место?

Я за минусы, если Вы не поняли. И за то, что полезной информации были больше, а не меньше.

Иногда комментарии получаются даже полезнее самой статьи

Полностью согласен, так это и хорошо. Но это и сложно. Сложно писать такие комменты.

А Хабр вместо поддержки таких авторов, делает наоборот - позволяет ставить минус молча. Моя статья и об этом.

Если поведение человека не нравится обществу, его минусуют.

У сообщества не может быть личной неприязни по определению.

Я не против минусов и критики, я против молчаливой критики. Типа такой: ты плохой.

  1. Контейнер решает именно ту задачу, которая описана в предыдущей статье и которая нужна для тестов: создает под дерево зависимостей по требованию с возможностью подмены зависимости на любом уровне. Например глубина дерева зависимостей 5, можно подменить только листовые зависимости.

  2. Никакой контейнер в go не упрощает код. Максимум делает его более структурированным. Потому что все равно придётся регистрировать все зависимости руками. Какой бы контейнер не был. Обьем пакета с зависимостями или конфигурации контейнера всегда примерно одинаков. Autowire невозможен, как в symfony.

  3. По сути это решение НЕ контейнер в классическом его понимании. Он не хранит мета информацию о связях и т.п. Это обычный пакет который создает зависимости. Только фабричные функции там обернуты в провайдеры. Провайдеры позволяют создавать зависимости лениво. Это позволяет в тестах создавать часть дерева зависимостей, и подменять зависимости на любом уровне.

Паралельный запуск условно возможен без изменений API, если добавить правильные локи в метод Use и Mock. Нужно над этим поразмыслить.


dc.SubService.Mock(mock1) 
service1 = dc.Myservice.Use()
dc.Reset()
// и тут же сделать 
dc.SubService.Mock(mock2) 
service2 = dc.Myservice.Use()
dc.Reset()

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

@alexac спасибо за конструктивный диалог

Information

Rating
453-rd
Registered
Activity