ну так из коллекции мы можем доставать и можем в коллекцию добавлять.
Слоистая архитектура для Yii приложений
Re: Слоистая архитектура для Yii приложений
Re: Слоистая архитектура для Yii приложений
Не совсем понял, можете поподробнее?zelenin писал(а): ↑2017.04.07, 09:23так интерфейс должен быть прописан, а не реализация - тогда менять ничего не придется.vitovt писал(а): ↑2017.04.07, 09:21Как я писал выше кто-то сразу в контроллере лезет в репозиторий
но тогда в случае смены репозитория надо везде во всех контроллерах менять код, а так только в одном сервисном слое. Нет? Да и в конторллере может понадобится не 1 репозитоий а 2 -5 (заказы, товары в заказе, клиенты и т.д.).Код: Выделить всё
class SiteController extends Controller { public function __construct(OrderRepository $repository) { $this->repository = $repository; } }
Re: Слоистая архитектура для Yii приложений
public function __construct(OrderRepositoryInterface $repository) {
интерфейс-то у нас не меняется, поэтому меняя реализации, у код менять не нужно.
интерфейс-то у нас не меняется, поэтому меняя реализации, у код менять не нужно.
Re: Слоистая архитектура для Yii приложений
А в случае когда надо 2-5 репозиториев, что все загонять в конструктор? Как я писал выше, например, надо в контроллере вывести заказ #5
Код: Выделить всё
$this->orderRepository->findOne(5);
Re: Слоистая архитектура для Yii приложений
вопрос в чем? 5 репозиториев - 5 интерфейсов. В чем вопрос?vitovt писал(а): ↑2017.04.07, 10:30А в случае когда надо 2-5 репозиториев, что все загонять в конструктор? Как я писал выше, например, надо в контроллере вывести заказ #5
а теперь тут же посчитать количество товары или вывести все товары в заказе?Код: Выделить всё
$this->orderRepository->findOne(5);
Re: Слоистая архитектура для Yii приложений
Если у вас конструктор контроллера требует больше 3-4 сервисов - ваш контроллер имеет слишком много обязанностей. Надо разделять по разным контроллерам. Ну либо внедрение метода (чего в yii вроде как нет) по экшенам.
Re: Слоистая архитектура для Yii приложений
В вопросе разделения на слои можно дойти до безумства. Смотря на пример который мы тут рассматриваем - заказы легко запутаться и пойти не в ту сторону.
Например, как я писал выше, у заказа есть товары, клиент
репозиторий Заказы возвращает объект Заказа, который в себе должен \ может содержать информацию только о себе, верно? Значит чтобы получить и заказ и список товаров или хотя бы количество товаров в заказе - нужно второй репозиторий задействовать и делать так:
1. Выбрал заказ
2. Выбрал товары по заказу
3. Выбрал клиента по заказу
Вот с этим получается путаница, потому, как в AR в частности в YII очень легко поддаться магии в виде Relations и возвращения каких-то связанных данных из других таблиц используя геттеры. (Например выбрал Заказ, у него есть метод getItems() который отдает заказы, есть метод hasItems() который дергает countItems() который смотрит количество заказов и т.д.
Re: Слоистая архитектура для Yii приложений
Re: Слоистая архитектура для Yii приложений
Попробовал предложенный способ в качестве рефакторинга проекта на Yii1. Толку мало. Тестировать сервисы модульными тестами без БД не получается, так как AR в Yii1 при конструировании лезет в БД за схемой! В Yii2 пока не пробовал, посмотрим что там.
UPD. Беглый просмотр кода yii\db\ActiveRecord показал, что присваивание любых свойств которые хранятся в _attributes приведет к вызову метода attributes(), который также полезет за схемой.
В общем, при проверке предложенный способ лишился своей главной прелести - чистого модульного тестирования сервисов, что, на мой вгляд, сильно уменьшило его полезность.
P.S. Если хотите модульное тестирование - забудьте про Yii AR.
UPD. Беглый просмотр кода yii\db\ActiveRecord показал, что присваивание любых свойств которые хранятся в _attributes приведет к вызову метода attributes(), который также полезет за схемой.
В общем, при проверке предложенный способ лишился своей главной прелести - чистого модульного тестирования сервисов, что, на мой вгляд, сильно уменьшило его полезность.
P.S. Если хотите модульное тестирование - забудьте про Yii AR.
Re: Слоистая архитектура для Yii приложений
Спасибо за ссылку, но это не сильно поможет. Например ProductCreator - он ведь создает оператором new AR Product. Можно конечно в фабрику вынести, но это еще большие костыли.
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Слоистая архитектура для Yii приложений
Я ничего не говорил о том что в сервис отдавать, я написал про то что сервис возвращает.
Форматирование это дело шаблонов, особенно если юзается шаблонизатор, это уже куча классов обрабатывающих данные, зачем тут еще какие-то декораторы? Если у нас DTO - User, и на двух страницах надо вывести дату регистрации в разном формате, надо два декоратора?
Кому нужны такие сложности?
Ок. Я в курсе про это паттерн. Но как и все паттерны надо использовать там где они не обходимы а не лишь бы юзать.
Паттерны создания объектов нужны для сложных инициализаций а не для обертки на конструктором.
Не знаю наверное мы разные статьи читали, с разным кодом. То что я видел там везде __get, __call, из-за генериков.
Это какие такие "много обязанностей"? Я вижу только одну, обработать запрос, делегировать обработку в сервис и подготовить ответ.
Жду Yii 3!
Re: Слоистая архитектура для Yii приложений
Создать два простых класса это ой как сложно, прям капец)slavcodev писал(а): ↑2017.04.11, 04:29 Форматирование это дело шаблонов, особенно если юзается шаблонизатор, это уже куча классов обрабатывающих данные, зачем тут еще какие-то декораторы? Если у нас DTO - User, и на двух страницах надо вывести дату регистрации в разном формате, надо два декоратора?
Кому нужны такие сложности?
Тут все дело в зависимостях. Отдельные DTO для шаблонов нужны для того, чтобы снизить зависимость шаблонов от домена. (VIEW от MODEL в MVC) Используя отдельный DTO, будет очень легко заменить User на какую-то другую DTO или сущность, два, три других класса, не трогая код шаблона, который зависит только от DTO.
Тут дело вкуса. Named constructor очень прост и удобен, у него нет недостатков. Он не предназначен для сложной инициализации. Это просто конструктор и именем и все.
Re: Слоистая архитектура для Yii приложений
Я бы делала все в методах одного репозитория: getOrder(), getOrderWithItems() и тп. И в репозитории уже скрыто, как мы получаем item к заказу, через отношения модели или вывозвом другого приватного метода с отдельным запросом. Т.к по сути это все заказ. Я "за" разумное использование отношений и AR-магии. Если это разные репозитории, то сервис должен думать о том, что заказ это один репозиторий, его товары это другой. А это мелочь, не вопросы уровня сервиса.vitovt писал(а): ↑2017.04.07, 14:53 Например, как я писал выше, у заказа есть товары, клиент
репозиторий Заказы возвращает объект Заказа, который в себе должен \ может содержать информацию только о себе, верно? Значит чтобы получить и заказ и список товаров или хотя бы количество товаров в заказе - нужно второй репозиторий задействовать и делать так:
1. Выбрал заказ
2. Выбрал товары по заказу
3. Выбрал клиента по заказу
Вот с этим получается путаница, потому, как в AR в частности в YII очень легко поддаться магии в виде Relations и возвращения каких-то связанных данных из других таблиц используя геттеры. (Например выбрал Заказ, у него есть метод getItems() который отдает заказы, есть метод hasItems() который дергает countItems() который смотрит количество заказов и т.д.
Re: Слоистая архитектура для Yii приложений
Roksalana писал(а): ↑2017.04.11, 11:28Я бы делала все в методах одного репозитория: getOrder(), getOrderWithItems() и тп. И в репозитории уже скрыто, как мы получаем item к заказу, через отношения модели или вывозвом другого приватного метода с отдельным запросом. Т.к по сути это все заказ. Я "за" разумное использование отношений и AR-магии. Если это разные репозитории, то сервис должен думать о том, что заказ это один репозиторий, его товары это другой. А это мелочь, не вопросы уровня сервиса.vitovt писал(а): ↑2017.04.07, 14:53 Например, как я писал выше, у заказа есть товары, клиент
репозиторий Заказы возвращает объект Заказа, который в себе должен \ может содержать информацию только о себе, верно? Значит чтобы получить и заказ и список товаров или хотя бы количество товаров в заказе - нужно второй репозиторий задействовать и делать так:
1. Выбрал заказ
2. Выбрал товары по заказу
3. Выбрал клиента по заказу
Вот с этим получается путаница, потому, как в AR в частности в YII очень легко поддаться магии в виде Relations и возвращения каких-то связанных данных из других таблиц используя геттеры. (Например выбрал Заказ, у него есть метод getItems() который отдает заказы, есть метод hasItems() который дергает countItems() который смотрит количество заказов и т.д.
Меня наверное смутила фраза, сказанная где-то тут или в соседней ветке, что типа одна реализация не должна знать ничего про другую. Вот я и растолковал, что грубо говоря на каждый объект DTO свой репозиторий который не знает про существование другого.
С другой стороны это же логично, что в целом система каким-то образом связана между собой. Т.е заказы должны знать про товары и клиентов, и наоборот ведь.
- slavcodev
- Сообщения: 3134
- Зарегистрирован: 2009.04.02, 21:42
- Откуда: Valencia
- Контактная информация:
Re: Слоистая архитектура для Yii приложений
Смешались в кучу кони люди.anton_z писал(а): ↑2017.04.11, 07:21 Создать два простых класса это ой как сложно, прям капец)
Тут все дело в зависимостях. Отдельные DTO для шаблонов нужны для того, чтобы снизить зависимость шаблонов от домена. (VIEW от MODEL в MVC) Используя отдельный DTO, будет очень легко заменить User на какую-то другую DTO или сущность, два, три других класса, не трогая код шаблона, который зависит только от DTO.
DTO нужны не для того чтоб шаблоны (каждый отдельно шаблон отделить от домена), а для того чтоб отделить два слоя. DTO может быть один на сущность, один ДТО представлять данные больше одной сущности, или может быть несколько ДТО на одну сущность. Правил тут нет, есть задача. Но вот только, делать отдельный ДТО для каждого шаблона, это перебор. Я бы сказал даже что мусор в приложении.
Сложность тут не в количестве классов, дело в поддержке.
- Новичкам въехать и запомнить каждый класс + к проблемам.
- В больших командах и большим приложением, не уследишь за изменениями а реакция на изменения в индустрии должны отражаться в приложении мгновенно, не когда разбираться и кучи лишних "простых классах"
Жду Yii 3!
Re: Слоистая архитектура для Yii приложений
DTO - это просто способ передавать в упакованном виде набор аргументов. DTO - это не полноценный класс/объект, а что-то вроде структур в Си (все свойства публичные, поведения нет). Если бы PHP поддерживал именованные параметры, то и без DTO можно было бы обойтись. Костыльная замена DTO в PHP – симфонийский OptionsResolver, но для него нет автокомплита в IDE.
Re: Слоистая архитектура для Yii приложений
каким образом?
какая связь optionsresolver и dto?
Re: Слоистая архитектура для Yii приложений
В случае именованных параметров (как в Objective-C, например), ты бы кидал в функцию что-то вроде:
Код: Выделить всё
$service->doTask(:name => $nameVar, :date => $date);
Код: Выделить всё
$service->doTask(:name => $nameVar, :date => $date, :status => $status);
Код: Выделить всё
$service->doTask(:name => $nameVar, :status => $status);
Код: Выделить всё
$dto = new NewTaskDTO;
$dto->name = $nameVar;
$dto->status = $status;
$service->doTask($dto);
Re: Слоистая архитектура для Yii приложений
Ну а OptionsResolver как раз эмулирует именованные параметры в пыхе. Отсюда и связь со всем вышеуказанным.