Этап
Готова
Тип
Рефакторнинг
Приоритет
Высокий
Трудоемкость
Сложная
Создана
Дата создания
3 года назад
Назначена
Обновлена
3 года назад

Сейчас это работает через самораспакоковывающийся из массива JlobObjectInterface объект.

Самораспаковывают его геттеры и сеттеры на работу с объектом вместо массива намекает UoW что проект всегда поменялся (массив сменился объектом умеющим toArray). В итоге любой flush чего-то связанного с проектом приводит к его пересохранению. Что ужасно, но зато обновляет дату проекта.

Варианты решения:

  • выделить слой бизнес-моделей в которые трансформеры будут выделать Проект со всеми его подобъектами. Но если я захочу его сохранять возникнет вопрос заного читать сущность? Искать её по своей реализации IM? Перебирать все поля в поисках изменившихся?
  • не хранить в сущностях большие объекты, а вместо этого отдельный сервис их получения из сущностей (И, возможно кеширования)

Второй вопрос касательно именно TaskSettings сейчас он хранит справочники, но в будущем будет хранить всякое/разное. При этом src/Dictionary/Fetcher.php получает из него справочники некоторой магией, храня в src/Dictionary/TypesEnum.php набор методов которые нужно вызвать для получения справочника. Это типа полиморфно, но не очень явно. Хотелось бы, чтобы можно было обойтись от неявности и видеть все вызовы ->getTaskSettings и ->getStages явно. Так что лучше бы инстанцировать справочники фабрикой. Тем более что Fetcher уже стал весьма непростым и немаленьким, хорошо бы его распилить. Это будем решать в tndt-84

От задачи зависит tndt-30. она уже сделанна

Панель управления

Комментарии могут оставлять только авторизованные пользователи
 demius 2 года назад

Красота, сейчас, спустя 8 месяцев она еще не в релизе, а я уже думаю как его вновь отрефаторить дальше.

 demius 2 года назад

В итоге здесь мы ограничились введением типа данных доктрины taskSettings. Сам объект практически не поменялся, как и fetcher

 demius 2 года назад

У задачи этап готова. интересно как же мы её решили, до того, как до 8ки обновились?

 demius 3 года назад

Вариант.

  • переделыываем конструкторы так, чтобы они принимали реальные атрибуты, а не массив.
  • объекты уровня выше массивы разбирают по атрибутам
  • тип данных taskSettings тоже разбирает массив по аттрибутам. Если решаем использовать serializer, вместо Reflection используем Constructor (это все равно не будет работать с array $items, но будет правильнее и быстрее, и поможет не создавать коллизий с нашими нестандартными get)
 demius 3 года назад

Тогда так. Ставим задачу на паузу. Если в ближайший релиз входит tndt-94 обновление системы, и система без проблем начинает работать на php8, оставляем так. Если нет, ставим phpDocumentator, и переключаем сериализатор на использование docBlock

 demius 3 года назад

Вторая веселая проблема: ReflectionExtractor заполняет считывает через get/set, которые т.е. предполагает, что будет работать с элементарным dto, а у нас в уже лежит всякая разная логика.

Хотя вроде бы мешает сейчас не логика, а то, что он по типу аргументов в set определяет какой объект инстанцировать. А там у меня array, так как в php7.4 нельзя установить DictionaryItem[]

Этому на самом деле тоже есть решение, надо вместо ReflectionExtractor использовать phpDocExtractor, но он требует себе пакет phpDocumentator, и везде аккуратно заполнять docBlock. И в целом можно и так сделать, но зачем, если в этом релизе мы уже запланировали переход на php8.

 demius 3 года назад

И так, распаковка внутренних объектов оказалось весьма непроста, но мы это победили. Для этого надо собирать serializer вручную через new, добавляя в ObjectNormalizer - ReflectionExtractor, которого из коробки в симфони нет, и нужно доставлять пакет property-info.

 demius 3 года назад

Кстати, рахз doctrineType не дает перегрузить конструктор, то может он вобще не сервис, это такая доктриновская инфраструктуа (под которую у нас правда нет диреткории), которую мы можем заполнять на старте. Т.е.

Doctrine->addType('taskSetting', ObjectType::class);
Doctrine->getType('taskSettings')->boot($serializer, TaskSettings::class);

Кстати, а в Kernel::boot() есть контейнер, чтобы оттуда достать сериализер? Или нам его в type создавать?

 demius 3 года назад

В этой итерации просто заводим в доктрине новый тип данных, с сериализацией TaskSettings. трансформацию entity в модели откладываем до разделения Application на Application/Infrastructure/Domain, ибо пока не понятно как их делить, нужны ли нам копии каждой сущности в виде модели и как хранить сущности пока система работает с моделью

 demius 3 года назад

Как сделать TaskSettings разрешенным типом атрибута смотри Enum в качестве атрибута сущности

 demius 3 года назад

Какой-то совсем некрасивый крстыль. Давайте лучше до деления на сущности и бизнес-модели, сделаем TaskSettingsFetcher делающий объект из сырых данных, либо заведем DoctrineType, этот объект десериализующий

 demius 3 года назад

Если мы решимправить ситуацию с пересохранениями TaskSettings до глобального рефакторинга с переходом на слоистую архитектуру мжно просто вставить костыль, $taskSettings с его get/set работают с массивом (или вобще строкой). Параллельно ему $_taskSettingsObj, сетящийся отдельно, например листенером или еще кем-то. Сразу с постановкой @todo в какой задаче мы это удалим.

 demius 3 года назад

Если мы переместим Entity в Infra/Entity или еще куда, у нас отвалятся комменты, так как они вешаются на класс, что некорректно. Так что перед задачей надо сделать tndt-109