169 похожих чатов

Добрый день! Прошу помочь найти корректную архитектуру. Чувствую, что или

запутался, или пытаюсь переусложнить.

В проекте мне нужно создавать различные отчеты, на основе которых будут происходить различные действия. Например, отчет о перемещении товара -> переместили товар. Отчет не равно действие, так как не все пользователи и не все отчеты предполагают моментальное исполнение - могут требовать подтверждения другим пользователем.

Сейчас реализовано так:
- Абстрактный Report (наследуется от Model), тут общие атрибуты для всех отчетов
- Наследующиеся от него Report[ТипОтчета], со своими атрибутами (хотя полагаю, что надо заменить на [ТипОтчета]Report)
- ReportController отдает нужные view или передает Request в ReportService (на самом деле public function store(ReportService $service) { ... $service->store(); ... })
- ReportService производит нужные действия - регистрирует отчет, позволяет заполнить его данными последовательно или сразу (тут два вида интерфейса, отсюда вариативность) и сохраняет отчет

Вопросы:
- Где стоит разместить функционал преобразования отчета в действие? Логично ли это сделать в Report как apply() и перезаписывать её в отчетах (public для вызова, внутри private, естественно)?
- Стоит ли выполнять действие напрямую $report->storageLocation->addInventory($report->storageItem, $report->quantity), или тут нужны Actions?
- Как вызывать её автоматически после создания для отдельных видов отчетов? Observer, Event, вызывать сразу из ReportService?
- Возможно, есть более логичный способ?

Заранее спасибо :)

5 ответов

14 просмотров

1. Возможно, нужна прослойка из сервисного слоя 2. Actions нужны, полагаю, для чистоты кода 3. Observer, Event , Queue, как решите 4. Думаю, что нет

всё зависит от того, как именно хотите автоматизировать процесс и как реализована архитектура БД, много нюансов

Ernesto- Автор вопроса
Александр Велижанин
1. Возможно, нужна прослойка из сервисного слоя 2....

Огромное спасибо за ответ :) Немного уточню: 1. Что-то вроде ReportApplyService, верно понял? Не могу пока понять, что он будет делать.. По итогу же все равно придется вызывать метод конкретного отчета. 2. Принял 3. Хм. Полагаю, что для гомогенности с ручным проведением, больше подходит Queue, спасибо! 4. 👍 С сервисной прослойкой пока не понял, предполагаю вот так: Класс ProcessReport (ShouldQueue), диспатчим с нужным Report, а вот дальше как пробросить до нужного экшна не понял. Всё так же возвращаюсь к методу модели Report - не будет ли это нарушением конвенций? Архитектуру БД стараюсь держать максимально простой, то есть все модели и связи реализованы родными средствами фреймворка - отсюда у меня и вопросы, раньше писал много спагетти-кода, сейчас хочу обойтись без велосипедов.

Ernesto
Огромное спасибо за ответ :) Немного уточню: 1. Чт...

Вообще лучше, думаю поделить отчёты на разные классы, чтобы не держать все в Report, иначе разрастание будет дикое, в каждом Action прокидываем нужный тип, можно и создать enum, если их немного и с помощью как раз разных типов Report организовывать разные проверки и бизнес-логику

Ernesto- Автор вопроса
Александр Велижанин
Вообще лучше, думаю поделить отчёты на разные клас...

Так они как раз и есть в разных классах и наследуются от Report. У каждого свой тип Enum есть, пока используется для авторегистрации всех типов отчетов. Отсюда я и думаю про public Report->apply() который обращается к private $this->applyReport(), который уже у каждого класса отчета свой, и ссылается на нужный Action.

Похожие вопросы

Обсуждают сегодня

Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
#include <stdio.h> #include <stdlib.h> #include <time.h> void mass_first_generate(int mass[5][7]) {     for (int N = 0; N < 5; N++) {         for (int A = 0; A < 7; A++) {   ...
Чувак
6
Всем привет! Решаю 99 OCaml Problems и столкнулся со следующей проблемой (прошу палками не забивать, я OCaml практически не трогал до этого момента): open OUnit2 let create_...
К|/|pи/\/\ 6е3yглbIи
2
Точно, оно. У тебя там имена потоков выставляются?
Александр (Rouse_) Багель
11
https://www.linkedin.com/posts/ugama-benedicta-kelechi-codergirl-103041300_mobiledevelopment-fluttertraining-handsonlearning-activity-7263445699227254784-IdHB?utm_source=share...
CoderGirl
16
возможно ли как-то передать в электрон или таури медиа поток с рендера 2д движка? двиг запускается как dll, а дальше надо как-то отправлять рендер кодировать не подходит, зр...
Kyle Nekto
7
Ну вот просто даже давайте вот как. Какой нибудь конкретный кейс, можете в пример привести, где бч работает и приносит прикладную пользу, а не просто что бы было? Не крипту.
Alexander Andreev
22
Помогите пожалуйста. Делаю систему плагинов. Проблема сейчас в такая: плагины загружаются в основном потоке. FLibHandle := SafeLoadLibrary(FFileName) Но нужно еще выполнить фу...
Илья 🤣
10
объясните пожалуйста, почему функция не работает должным образом? вроде должно брать активное окно сравнивать его размер с размером экрана, и если есть совпадение = true прове...
JF
12
лучше скажите, причём тут паскаль?
Alexey Kulakov
36
Карта сайта