Страница 1 из 8

Пример чистой архитектуры на оценку

Добавлено: 2019.09.18, 13:18
maleks
Приветствую.
Набросал пример основываясь на принципах чистой (clean) архитектуры
Сделал CRUD вокруг сущности "Пост блога" (PostController) и отображение постов на главной (SiteController)
По функционалу пока не усложнял, хочу на простой задаче уточнить. (Для простых проектов если)
Особенности:
- разделено на слои
- внутренние слои не зависят от внешних
--- если зависимость нужна то прокидывается через интерфейс лежащий во внутреннем слое
- Сущности в виде AR моделей, логику сохранения сюда не пишем
--- Потом возможно сюда доменную логику
--- Новую сущность создаем через фабрику в этом классе сущности
- Сохраняем в базу и выборки только через репозиторий
- Сервисный слой пока не сильно умным получился, но зацел на то чтобы он не просто как Transaction Script работал, а как тонкая прослойка к доменной сущности. (если получится)

ссылка на код

- Что видится правильным или не правильным?
- Может кто уже делал себе, крутил эти идеи (clean architecture) и сразу можно улучшить чем то?

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.18, 14:33
anton_z
Разрешите форки, покажу что бы я сделал по-другому) (на досуге, не мгновенно) Вообще я этой т. н. "чистой архитектурой" переболел и теперь просто решаю задачи, чего и всем желаю) Let it go)

P.S. Если хочется что-то изучать, удовлетворить потребность в познании, то я бы изучал СУБД или фронтенд, причем конкретные средства, на пресловутую "чистую архитектуру" я бы силушки не тратил, по мне не стоит оно того.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.18, 16:01
maleks
форки разрешены

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.18, 20:47
ElisDN
maleks писал(а): 2019.09.18, 13:18 - Разделено на слои
Метод rules() остался в сущности. Будут проблемы со сценариями.
PostService - это сервис приложения, а не домена. И ему не нужны return false.
maleks писал(а): 2019.09.18, 13:18 - Сохраняем в базу и выборки только через репозиторий
Сохранить одну сущность через репозиторий можно. Но как будете сохранять сущность с комментариями?
maleks писал(а): 2019.09.18, 13:18 Сущности в виде AR моделей, логику сохранения сюда не пишем
Пока это просто голые структуры с полями, а не сущности.

Блог с CRUD - это слишком примитивный пример. В нём нет логики и сложностей.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.19, 07:52
maleks
ElisDN писал(а):Метод rules() остался в сущности. Будут проблемы со сценариями.
В этой сущности я планировал оставить только тот rules() который генерируется gii.
Ничего другого туда не менять.
Формы берут его(для DRY) и меняют. Все сценарии, если нужны, в формах.
ElisDN писал(а):PostService - это сервис приложения, а не домена
Структуру изначально брал из - Kristopher Wilson THE CLEAN ARCHITECTURE IN PHP
Там:

Код: Выделить всё

src/
	Domain/
		Entity/
		Factory/
		Repository/ (тут интерфейсы)
		Service/
	Persistence/
		Repository/
Там сервисы походу не разделяют и UseCase и Entities - это же и есть домен.
ElisDN писал(а): И ему не нужны return false.
Ему тоже надо бросаться исключениями?
ElisDN писал(а): Пока это просто голые структуры с полями, а не сущности.
Блог с CRUD - это слишком примитивный пример. В нём нет логики и сложностей.
Я ж только начал создавать, уточнить на начальном.
Ведь если система работает, она должна и на простом работать.
ElisDN писал(а): Сохранить одну сущность через репозиторий можно. Но как будете сохранять сущность с комментариями?
Сразу пока не вижу usecase что одновременно надо сохранять и пост и комментарии.
Но все ж идет в транзакции.
Так что например из PostRepository дернуть CommentRepository и дать команду через него сохранить и соответствующие комменты

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.19, 10:33
samdark
Но как будете сохранять сущность с комментариями?
В этом конкретном случае никак. Это будет ошибкой.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.20, 07:44
maleks
В общем пока не буду уточнять разницу между сервисами домена и приложения, может это в других подходах.
В чистой архитектуре они use case-ы к доменным слоям относят:
Изображение
Просто обозначу их что это usecase

Код: Выделить всё

domain 
  entity
  repository
  service
  usecase

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.20, 16:52
samdark
Вот в том что выше вообще нет деления на infrastructure и application.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.21, 07:51
maleks
samdark писал(а): 2019.09.20, 16:52 Вот в том что выше вообще нет деления на infrastructure и application.
В том что выше на картинке? Или в моем коде?

Порыв еще эту тему думаю все таки остановиться чтобы выделить слой приложения, куда пойдут usecase-ы и такие вещи как TransactionServiceInterface. Вопрос - а имплементацию этого последнего интерфейса помещать на этом же слое приложения? Сейчас я эту имплементацию кинул в условный слой Инфраструктуры, по той логике что во внутренних слоях находятся интерфейсы, а реализации в более внешних(типа как в гексоганальной архитектуре с адаптерами). И это для всего подобного, сервиса почтовых сообщений того же.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.21, 08:36
maleks
ElisDN писал(а): 2019.09.18, 20:47 Сохранить одну сущность через репозиторий можно. Но как будете сохранять сущность с комментариями?
Вы наверное имели ввиду способ когда Комменты добавляются к сущности Post как у вас тут Employee->addPhone() ?
Для комментов я так не думал делать, они сами сущности.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.21, 14:22
samdark
В том что выше на картинке? Или в моем коде?
На картинке.

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.21, 14:51
maleks
Ну они в чистой архитектуре таким термином как инфраструктура не пользуются, но как правило под ним понимается обращение с "внешними" вещами, с БД в основном

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.21, 19:46
samdark
Давайте лучше отвечу на вопрос из начального поста.
- Что видится правильным или не правильным?
Вопрос можно трактовать двояко:

1. Правильно ли реализован тот или иной паттерн? Правильно ли я его понял?
2. Правильно ли решена проблема?

Ответы таковы:

1. Допустим, что вопрос "правильно ли я реализовал clean architecture". Этот вопрос нормален если проект учебный и цель — научиться правильно реализовывать паттерн и понять его. В общем идея чистой архитектуры в полном отделении доменного слоя от деталей работы с данными и отрисовки всего этого.

С этой точки зрения ошибки:

- Active Record использован как доменные модели. Сущность знает как она хранится.
- PostSearch жёстко завязан на Post. Это как следствие предыдущего пункта.
- В view беда. Вроде есть отдельная view model (форма), но зачем-то в шаблоны тащится ещё и доменная сущность.

2. А вот это самый интересный вопрос, который уже ближе к реальности.

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

Если проводить аналогию с паттернами кода, то вы реализовали синглтон потому что он модный и спрашиваете, верно ли всё. Пропущено несколько важных этапов:

- Анализ решаемой проблемы.
- Выделение мест, которые должны быть гибкими.
- Выделение болей. Поиск паттернов, которые могут их решить или изобретение решений (это часто не хуже).
- Повторный анализ решения, которое получится. Можно ли проще?

Собственно, в реальном проекте делать 1 без 2 — великое зло, которое я раньше неосторожно называл "паттернизмом" за что огребал критики. Ни одна задача не должна делаться бездумно. И думать нужно начинать с "какую проблему мы решаем"?

Если вдруг этот вопрос я плохо раскрыл, почитайте старую заметку (https://rmcreative.ru/blog/post/khorosh ... -slozhnost) и более опытных, чем я, разработчиков: https://blog.pragmaticengineer.com/soft ... overrated/

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.22, 15:41
maleks
samdark писал(а): 2019.09.21, 19:46 1. Допустим, что вопрос "правильно ли я реализовал clean architecture". Этот вопрос нормален если проект учебный и цель — научиться правильно реализовывать паттерн и понять его. В общем идея чистой архитектуры в полном отделении доменного слоя от деталей работы с данными и отрисовки всего этого.
Разве подходы с clean architecture - это для учебных проектов?
Идея посмотреть насколько оно съедобное получится. Для реалий.
Ведь что мы имеем по умолчанию: своеобразную трактовку MVC когда в AR пихается тупо все, а что не влезло - в контроллере.
Основная идея этой архитектуры разделить на слои и чтобы вещи из внутренних слоев не зависели от вещей из внешних слоев.
Доменный у меня от вьюх и БД не зависит.
Мы тут не на DDD замахиваемся.
samdark писал(а): 2019.09.21, 19:46 - Active Record использован как доменные модели. Сущность знает как она хранится.
Вот пока тут этап "для реалий". Без AR отвалится тележка и ворох готового. И вносить в проект DataMapper - это довольно большая задача.
И что с того что AR "знает", если ее сохранять будут только через репозиторий, т.е. это он по сути теперь "знает".
samdark писал(а): 2019.09.21, 19:46 - PostSearch жёстко завязан на Post. Это как следствие предыдущего пункта.
- В view беда. Вроде есть отдельная view model (форма), но зачем-то в шаблоны тащится ещё и доменная сущность.
Вещи с внешних слоев могут использовать вещи с внутренних.
Можно конечно dto-шками все границы переходить, но опять же не отгребем ли кучу проблем, перестанут все эти GRID-ы работать.
PostSearch сейчас работает также само как и всегда по умолчанию работал, людям будет понятен такой код

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.22, 16:20
anton_z
maleks писал(а): 2019.09.22, 15:41
Ведь что мы имеем по умолчанию: своеобразную трактовку MVC когда в AR пихается тупо все, а что не влезло - в контроллере.
Да просто надо с умом подходить к Yii и к AR, тогда проблем не будет таких. Для начала хотя бы формы от AR отпилить, уже много чего даст.
Валидацию в AR я оставляю в качестве проверки данных на соответствие требованиям БД, чтоб ерунда всякая не могла туда записаться. Если AR не прошла валидацию - исключение.

ИМХО, если проект уже есть и он на Yii, не надо его пытаться под Clean Architecture загнуть (по моему опыту получится еще хуже чем было), надо просто устранить проблемы, которые есть в проекте. Сформулируйте, что вам не нравится, чего не хватает, что бы вы хотели сделать. Пока проблема видится как "хочу чистую архитектуру".

P.S. Пример пока сделать руки не дошли, на неделе постараюсь)

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.23, 00:31
samdark
Вы опять комментируете по учебному проекту, и игнорируете, собственно, главный вопрос: "какую именно боль вы пытаетесь вылечить?".

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.23, 05:16
rugabarbo
samdark писал(а): 2019.09.23, 00:31 Вы опять комментируете по учебному проекту, и игнорируете, собственно, главный вопрос: "какую именно боль вы пытаетесь вылечить?".
Боль автора: интерес к DDD (:

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.23, 10:08
maleks
samdark писал(а): 2019.09.23, 00:31 "какую именно боль вы пытаетесь вылечить?".
Человек крутящийся в мире yii, с его MVC подходом, по умолчанию получает боли:
1. Сильносвязанный код
2. Связи причем всего со всем, т.к. из коробки нет никаких намеков на разделение на слои
3. Это все не готово к жизни в agile, когда постоянно будет все меняться и надо переписывать, это потребует многих изменений
4. Т.к. на покрытие тестами в наших реалиях почти везде забивают финансово пункт 3 усугубляется теперь уже неуверенностью в правильной работе
5. Опять же в команде нет никакого регламента как новым людям стоит писать код. Ведь все что не запрещено - разрешено.

Можно пытаться посимптомно лечить одно, второе, все эти "боли", но что если можно избавляться не от симптомов а от причины.
Поэтому смотрим что в этом мире уже Фаулер и ко намозговали.
Сейчас же по сути как не было готового рецепта как получше собирать на yii, так и нет(*).
Каждый пытается по своему.
Зачастую получается просто миграция Transaction Script из контроллера в сервис или даже встречал что в репозиторий.
Мало того что это процедурщина, она еще не подтверждена никакой четкой логикой, и чуть что нарушается.


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

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.23, 10:17
maleks
anton_z писал(а): 2019.09.22, 16:20 Да просто надо с умом подходить к Yii и к AR, тогда проблем не будет таких
Я довольно долго пытался найти рецепты "правильной" готовки AR, но ничего не нашел, думаю этого не существует в природе.
anton_z писал(а): 2019.09.22, 16:20 . Пока проблема видится как "хочу чистую архитектуру".
Проект не старый. Проблема: есть новый проект, КАК ЕГО ПИСАТЬ.
Естественно учитывая требования ООП. SOLID тот же. Забить на всю критику "старых путей", критику например этого раздела?

Re: Пример чистой архитектуры на оценку

Добавлено: 2019.09.23, 12:58
samdark
1, 2. Фреймворк за вас думать не будет. Слои вас сами по себе не спасут. Да, в Yii 2 очень соблазнительно использовать service locator по делу и без, но можно либо использовать контейнер, либо органичить себя и использовать SL только в контроллере.
3. Вполне готово. Мы так stay.com писали, например. Когда churn подскакивал у какого-то куска кода, делали его более гибким и сильнее покрывали тестами.
4. Слои не дадут уверенности. Они никак не заменяют тесты.
5. Если в команде нет регламента, то тимлид (или другой главный) команды не выполнил свою работу.

https://habr.com/ru/post/467997/
Проблема: есть новый проект, КАК ЕГО ПИСАТЬ.
Естественно учитывая требования ООП. SOLID тот же.
Нет требований ООП или требований SOLID. Это полезные принципы, которые позволяют написать код, который меньше ломается. Но это не боли, которые нужно решать. Это инструменты.

В проекте есть проблемы, которые он действительно должен решать. И вот на них и стоит фокусироваться.