Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54

Clean Architecture. Отображение в пользовательском интерфейсе процесса выполнения длительной бизнес-операции

12.09.2024, 12:01. Показов 1275. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Стараюсь написать программу с "правильной" архитектурой.
Прочитал про Чистую архитектуру:
https://habr.com/ru/articles/499078/

Как я понял, в соответствии с Чистой архитектурой, выходные данные бизнес-операции (Use Case Interactor) при выполнении "возвращаются" в вызывающий слой в виде OutputPort.
Но ведь OutputPort "возвращается" при завершении бизнес-операции, через OutputPort возвращаются результаты выполнения.

А как сделать, чтобы происходило изменение пользовательского интерфейса именно в процессе выполнения длительной бизнес-операции?

Например.
Бизнес-операция - это обработка вложенных файлов и папок. Обработка каждой папки достаточно длительная.
Нужно, чтобы при выполнении этой операции в окне отображалась таблица с колонками.
При начале обработки новой папки\подпапки в таблице должна появляться новая строка и в первой колонке "Имя папки" таблицы отображается имя папки.
По ходу обработки папки (при обработке очередного файла в этой папки) во второй колоке "Файл" должна появиться строка "обрабатывается файл ххххх". После обработки всех файлов в колонке таблицы "Результат" должен появиться результат обработки папки.

В общем-то по смыслу ничего сложного.
Но как это реализовать, придерживаясь принципов Clean Architecture?
Что дожлна сделать процедура бизнес-операции, чтобы "сработали" все эти OutputPort, Presenter и т.д., и чтобы в итоге пользователь видел процесс заполнения таблицы?

Объясните, пожалуйста.
Если можно - покажите какой-нибудь подходящий пример кода.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.09.2024, 12:01
Ответы с готовыми решениями:

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

Clean Architecture (MVP), как обойтись без Context для Data Layer
На сколько я понял разделение по слоям, мы должны избегать использования Context где бы то ни было, кроме View. Я понимаю, что четких...

Class в пользовательском интерфейсе
Доброво времени суток всем, подскажите пожалуста в чём ошибка, пишет что собственный тип не может быть вложен в управляемыи... как тогда...

14
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
12.09.2024, 16:32
Цитата Сообщение от zelenprog Посмотреть сообщение
А как сделать, чтобы происходило изменение пользовательского интерфейса именно в процессе выполнения длительной бизнес-операции?
Операция выполняется асинхронно. Одним из параметров является функция обратного вызова, которая вызывается после завершения каждого этапа обработки.

Это общий принцип. Конкретные детали зависят от того, что за UI у Вас. Например, возможно, у Вас будет опрос сервера в цикле (о текущем статусе операции).
0
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
12.09.2024, 16:51  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Одним из параметров является функция обратного вызова, которая вызывается после завершения каждого этапа обработки.
... возможно, у Вас будет опрос сервера в цикле (о текущем статусе операции).
А что в данном случае будет OutputPort?
И как надо разделить эти действия между объектами Controller, Presenter?

Как я понимаю, моделью в этой программе будут данные о папках, файлах и результатах их обработки.
Верно?
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,830
Записей в блоге: 2
12.09.2024, 20:44
Цитата Сообщение от zelenprog Посмотреть сообщение
А как сделать, чтобы происходило изменение пользовательского интерфейса именно в процессе выполнения длительной бизнес-операции?
Через переходник/адаптер. Псевдокод
C++
1
2
3
4
5
6
7
8
9
10
11
void RenderFrame( void )
{
...
  SetProgress(0, num_steps, ...);
...
  for (auto * data : slab) {
...
    if (!UpdateProgress(1)) return;   // обновляем индикатор и проверяем cancel
...
  }
}
Конечно используемые вызовы (SetProgress, UpdateProgress) непрозрачны для расчетов. Др словами расчет не никаких деталей UI. Индикатор может быть развесистое окно, но может и строка в консоли
0
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
13.09.2024, 08:34  [ТС]
Цитата Сообщение от Igor3D Посмотреть сообщение
Через переходник/адаптер. Псевдокод...
Общая схема понятна.
А вот более конкретные моменты не понятно как надо делать.

Цитата Сообщение от Igor3D Посмотреть сообщение
SetProgress(0, num_steps, ...)
По условию в окне интерфейса должны отображаться не просто прогресс, а именно подробная информация о выполняемых действиях. Причем, каждое действие должно сообщить о себе "свои" подробности. Например, действие архивации должно сообщить имя созданного архива и его размер, действие переноса папки должно сообщить о количестве файлов и куда они перенесены.
Как эту информацию из слоя бизнес-логики передать в вызывающий слой интерфейса?

И второй вопрос - мне все-таки хотелось бы это реализовать в рамках "Чистой архитектуры".
В вашем примере метод "void RenderFrame( void )" - это UseCase Interactor.
А где код, который выполняет роль InputPort и OutpputPort?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
13.09.2024, 10:29
Цитата Сообщение от zelenprog Посмотреть сообщение
Как я понимаю, моделью в этой программе будут данные о папках, файлах и результатах их обработки.
Верно?
Да. Классы, специфичные для бизнес-логики, являются моделью.

Добавлено через 2 минуты
Цитата Сообщение от zelenprog Посмотреть сообщение
не просто прогресс, а именно подробная информация о выполняемых действиях
Единственная разница, вместо числа (процент прогресса) будет объект (данные о прогрессе).

Добавлено через 4 минуты
Возможно, с учётом веб специфики будет проще реализовать функцию, которая выполняет операцию, на клиенте. На сервере будет выполняться отдельный шаг.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,830
Записей в блоге: 2
13.09.2024, 20:36
Цитата Сообщение от zelenprog Посмотреть сообщение
И второй вопрос - мне все-таки хотелось бы это реализовать в рамках "Чистой архитектуры".
В вашем примере метод "void RenderFrame( void )" - это UseCase Interactor.
А где код, который выполняет роль InputPort и OutpputPort?
Я не пытаюсь осуждать прочитанное Вами, но я и не обязан это принимать/изучать, мне все равно кто там In/Out port. Любой опытный программист придумывает свою такую/подобную систему

Цитата Сообщение от zelenprog Посмотреть сообщение
По условию в окне интерфейса должны отображаться не просто прогресс, а именно подробная информация о выполняемых действиях. Причем, каждое действие должно сообщить о себе "свои" подробности. Например, действие архивации должно сообщить имя созданного архива и его размер, действие переноса папки должно сообщить о количестве файлов и куда они перенесены.
Как эту информацию из слоя бизнес-логики передать в вызывающий слой интерфейса?
Да, бизнес-логика (как коряво это звучит), должна подготовить и передать все данные для UI, обычно в виде структуры. Да, если UI переделывается и эти данные меняются - нужно вносить изменения в слой бизнес-логики. Какой-то полной/абсолютной "независимости" не существует. Важно что бизнес-логика не завязана на использование этих переданных данных. Хорошая проверка: а будет ли бизнес-логика работать без UI, напр с командной строкой?
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
14.09.2024, 13:10
Цитата Сообщение от Igor3D Посмотреть сообщение
Да, если UI переделывается и эти данные меняются - нужно вносить изменения в слой бизнес-логики.
В достаточно крупном приложении имеет смысл выделить "уровень приложения".

Уровень данных - "бездумное" сохранение сущности.
Уровень бизнес-логики - сохранение сущности с учётом бизнес-правил и инвариантов.
Уровень приложения - сохранение сущности, специфичное для данного приложения (включая маппинг сообщений об ошибках и прочее).
0
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
16.09.2024, 10:09  [ТС]
Цитата Сообщение от Igor3D Посмотреть сообщение
Я не пытаюсь осуждать прочитанное Вами, но я и не обязан это принимать/изучать, мне все равно кто там In/Out port. Любой опытный программист придумывает свою такую/подобную систему
Мне кажется, что ничего придумывать не надо. Это просто прицип SRP, который обязательно дожен соблюдаться в любой программе. Я думаю, что любой программист в том или ином виде применяет этот подход. Если он его знает, то просто применяет. Если не знает, то программист вынужден "придумывать свою систему", хотя по сути эта "его" система будет аналогичной многим другим уже давно используемым системам.
Просто автор "Чистой архитектуры" дал своеобразные названия классам этой "системы": Controller, Presenter, InputPort, OutputPort, UseCaseInteractor.

Добавлено через 2 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Да, бизнес-логика (как коряво это звучит) ...
Согласен, звучит очень коряво. Буквально пару дней назад обсуждали это с коллегами.
А как назвать по другому? Было предложение назвать "деловая логика" или "предметная логика" - это и по сути ближе и звучит более "по русски".

Добавлено через 2 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
В достаточно крупном приложении имеет смысл выделить "уровень приложения".
Уровень данных - "бездумное" сохранение сущности.
Уровень бизнес-логики - сохранение сущности с учётом бизнес-правил и инвариантов.
Уровень приложения - сохранение сущности, специфичное для данного приложения (включая маппинг сообщений об ошибках и прочее).
А что значит "сохранение сущности"?
Обычно для сохранения используется репозиторий. Вы имеете ввиду репозиторий?

Добавлено через 43 минуты
Кстати...
В моей задаче есть требование отображать ход выполнения в виде таблицы.
Если бизнес-слой будет отдавать клиенту только данные о каждой выполненной операции, то откуда на клиенте возьмется таблица? Значит, таблицу какой-то модуль должен создавать. Как мне кажется, интерфейс не должен заниматься созданием таблицы.

Может быть действительно надо использовать репозиторий?
Например, всю информацию о ходе выполняемых действий записывать в слое бизнес-логики в репозиторий, и отдавать клиенту список из этого репозитория?
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,830
Записей в блоге: 2
16.09.2024, 12:29
Цитата Сообщение от zelenprog Посмотреть сообщение
Мне кажется, что ничего придумывать не надо. Это просто прицип SRP, который обязательно дожен соблюдаться в любой программе. Я думаю, что любой программист в том или ином виде применяет этот подход. Если он его знает, то просто применяет. Если не знает, то программист вынужден "придумывать свою систему", хотя по сути эта "его" система будет аналогичной многим другим уже давно используемым системам.
Просто автор "Чистой архитектуры" дал своеобразные названия классам этой "системы": Controller, Presenter, InputPort, OutputPort, UseCaseInteractor.
Да не будет оно так просто, прочитал и применил. При проектировании классов раздумья неизбежны, и "теория" (или чужой опыт) может как помогать, так и мешать. Я верю что человек на хабре написал статью честно, и в его проекте все хорошо легло/получилось. Но это совершенно не значит что у Вас тоже будет так. Пока я вижу Вам угрожает чрезмерно теоретизированная, слишком абстрактная система с массой заглушек (не помню как называется этот антипаттерн).

Цитата Сообщение от zelenprog Посмотреть сообщение
В моей задаче есть требование отображать ход выполнения в виде таблицы.
Если бизнес-слой будет отдавать клиенту только данные о каждой выполненной операции, то откуда на клиенте возьмется таблица? Значит, таблицу какой-то модуль должен создавать. Как мне кажется, интерфейс не должен заниматься созданием таблицы.
Почему не должен? Что здесь плохого, и почему UI не может этим заняться? Какие аргументы кроме "так кажется"? Хотя возможно это и дело расчетной части (пресловутой бизнес-логики). И выделение отдельно - тоже свои резоны. Во всех 3 случаях нельзя сказать "это ошибка".
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
16.09.2024, 16:24
Цитата Сообщение от zelenprog Посмотреть сообщение
А что значит "сохранение сущности"?
Работа в приложении сводится к изменению данных. Чаще всего это сохранение в БД.

Репозиторий (или аналоги) - это "бездумное" сохранение. По сути - это отображение сущности на таблицу.

Цитата Сообщение от zelenprog Посмотреть сообщение
Как мне кажется, интерфейс не должен заниматься созданием таблицы.
Именно интерфейс и должен заниматься созданием html-таблицы.

Цитата Сообщение от zelenprog Посмотреть сообщение
Например, всю информацию о ходе выполняемых действий записывать в слое бизнес-логики в репозиторий, и отдавать клиенту список из этого репозитория?
Лучше не писать в БД ненужную информацию. И вообще, бизнес-логика не должна знать, как и что выводится в интерфейсе.
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,830
Записей в блоге: 2
16.09.2024, 17:07
Цитата Сообщение от Shamil1 Посмотреть сообщение
Именно интерфейс и должен заниматься созданием html-таблицы.
html нет, но какую-то "data model" на базовых контейнерах вполне можно слить и в расчеты

Цитата Сообщение от Shamil1 Посмотреть сообщение
И вообще, бизнес-логика не должна знать, как и что выводится в интерфейсе.
Безусловно. А обратное? Как-то выходит что "UI все знает"
0
0 / 0 / 0
Регистрация: 22.09.2023
Сообщений: 54
17.09.2024, 09:07  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Репозиторий (или аналоги) - это "бездумное" сохранение. По сути - это отображение сущности на таблицу.
Цитата Сообщение от zelenprog Посмотреть сообщение
Уровень бизнес-логики - сохранение сущности с учётом бизнес-правил и инвариантов.
Уровень приложения - сохранение сущности, специфичное для данного приложения (включая маппинг сообщений об ошибках и прочее).
Понял. Вы имеете ввиду разные "уровни" сохранения?
Только не совсем понял про сохранение на уровне приложения. Что значит "маппинг сообщений об ошибках"? Что такое "прочее"? Можно пример?

Добавлено через 8 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
>> ... всю информацию о ходе выполняемых действий записывать в слое бизнес-логики в репозиторий, и отдавать клиенту список из этого репозитория?
Лучше не писать в БД ненужную информацию. И вообще, бизнес-логика не должна знать, как и что выводится в интерфейсе.
Вопрос конечно интересный: является ли информация о выполняемых действиях частью бизнес-логики? И должна ли она сохраняться?
По условиям задачи бизнес-логика должна все свои действия "регистрировать". Это не "ненужная" информация.
А раз так, значит ее надо где-то сохранять. Бизнес-логика не будет знать как эта информация выводится в интерфейсе, она просто фиксирует информацию о выполняемых действиях.
Еще одним "аргументом" "за" сохранение этой информации может быть следующий момент. Допустим клиент в какой-то момент "отвалился", через некоторое время снова подключился. По идее в этом случае клиент должен отобразить те действия, уведомления о которых он пропустил. А значит, клиент должен их прочитать из какого-то хранилища.
Получается, все-таки информация о выполняемых действиях - это часть бизнес-логики.
Верно я рассуждаю?

Добавлено через 1 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
Именно интерфейс и должен заниматься созданием html-таблицы.
Тут речь о разных таблицах. Одна таблица - это которая отображается в интерфейсе, а другая "таблица" (это условное название, точнее - это репозиторий) - это которая "накпливает" информацию о выполненных действиях.

Добавлено через 2 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Пока я вижу Вам угрожает чрезмерно теоретизированная, слишком абстрактная система с массой заглушек (не помню как называется этот антипаттерн).
Ну вот я и обратился сюда за помощью, чтобы сделать логичную работающую систему, которую можно будет развивать и поддерживать.
0
Модератор
Эксперт функциональных языков программирования
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,877
17.09.2024, 17:30
Цитата Сообщение от zelenprog Посмотреть сообщение
является ли информация о выполняемых действиях частью бизнес-логики? И должна ли она сохраняться?
Если это указано в описании Системы (требованиях к Системе), то да.

Цитата Сообщение от zelenprog Посмотреть сообщение
Вы имеете ввиду разные "уровни" сохранения?
Например, есть сущность типа Документ1.
Метод в репозитории (уровень данных) просто сохраняет документ1 в таблицу Документ1.
Метод в домене (уровень бизнес-логики) при сохранении валидирует документ1 (например, проверяет наличие нужного значения в справочнике) и, при необходимости, вносит изменения в связанные сущности.
Метод в приложении может, например, может автоматически добавлять в справочник нужное значение. Или создавать сразу несколько документов, подставлять значения по-умолчанию для некоторых полей и т.п.

Цитата Сообщение от zelenprog Посмотреть сообщение
Что значит "маппинг сообщений об ошибках"?
Предположим, мы вызываем метод уровня приложения для создания документа. В этом методе вызывается метод бизнес-логики, который, в свою очередь, вызывает метод репозитория. Этот метод возвращает исключение с текстом, который, возможно, понятен только программисту. Например, "The DELETE statement conflicted with the FOREIGN KEY constraint ..." Метод в бизнес-логике перехватывает это исключение и возвращает исключение с текстом, понятным тому, кто будет разбираться с этой ошибкой (например, сотруднику службы поддержки). При необходимости, это сообщение пишется в лог, но показывать этот сообщение пользователю бессмысленно и даже вредно. Ему нужно вернуть сообщение (на нужном языке), отвечающее на три вопроса: что случилось? почему? что делать? Наиболее важен ответ на последний вопрос (что делать?). Причём, текст сообщения в интерфейсе пользователя, скорее всего, будет отличаться от текста сообщения в интерфейсе оператора или администратора
0
1967 / 823 / 114
Регистрация: 01.10.2012
Сообщений: 4,830
Записей в блоге: 2
17.09.2024, 17:53
Цитата Сообщение от zelenprog Посмотреть сообщение
Верно я рассуждаю?
Да может и верно, но в стартовом посте нет никаких упоминаний о "клиенте" который может "отвалиться", о каких-то СУБД, о необходимости регистрации и др. Не исключено что в Вашем следующем посте будет еще больше нового Такой разговор/обсуждение беспредметны
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.09.2024, 17:53
Помогаю со студенческими работами здесь

Отображение процесса выполнения
Может еще кто нибудь подскажет как привязать progresbar к процесу? Достаточно что прогресбар просто крутился пока выполняется процес ...

В графическом пользовательском интерфейсе ввести данные в виде таблицы
Здравствуйте. Нужно в графическом пользовательском интерфейсе ввести данные в виде таблицы ( ф.,и.,о. вкладчика, номер счета, сумма...

В отдельном потоке вычислить уравнение; результат отобразить в пользовательском интерфейсе
Ребят, есть задание, ток начали С# и потоки. В общее не чего не понимаю и буду правда благодарен за помощь . Написать программу: В...

В отдельном потоке вычислять значение w и непрерывно обновлять его в пользовательском интерфейсе
Создайте приложение, в отдельном потоке вычисляющее значение w и непрерывно обновляющего его в пользовательском интерфейсе. Для расчета...

Отображение прогресса выполнения операции
Привет. Допустим есть рабочий поток, который выполняет некую трудоемкую операцию, и поток UI. Необходимо на UI отображать процент...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru