Russian Qt Forum
Ноябрь 25, 2024, 17:03 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: Паттерн наблюдатель  (Прочитано 38075 раз)
Vamireh
Гость
« : Апрель 07, 2016, 09:03 »

Есть класс по загрузке неких файлов, например. В нем есть сигнал, который информирует о проценте загрузке. В слоте, соответственно, меняется значение QProgressBar. А как бы вы это сделали без Qt только на C++? Только идея интересует. boost:signals, собственный велосипед или еще что-то.

Также интересны ответы в случае, когда файл в структуру грузит функция C в dll, а прогрессбар должен меняться в приложении C#, например.

Просто понял, что меня бы подобная задача озадачила бы слегка. Коряво, сделал бы, но интересно как это сделают гуру.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Апрель 07, 2016, 09:57 »

Паттерн наблюдатель здесь явно избыточен. Нормально напр так
Код
C++ (Qt)
UpdateProgress progress("My Dialog Title", DELAY_BEFORE_SHOW);
UpdateIndicator indicator("Process Name", "Units name", 0, MAX_ITERATION, UPDATE_STEP);
 
for (int i = 0; i <  MAX_ITERATION; ++i) {
DoCalc(i):
progress.Update(1);
if (progress.cancelled()) break;
}
Ну конечно вызывающий не знает что делают UpdateProgress/Indicator - может рисует окно, может печатает в консоль а может и вообще ничего. А в реализации этих классов уже заниматься конкретикой. Да,  и особой выгоды от слот/сигналов здесь не видно

Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #2 : Апрель 07, 2016, 11:36 »

Есть класс по загрузке неких файлов, например. В нем есть сигнал, который информирует о проценте загрузке. В слоте, соответственно, меняется значение QProgressBar. А как бы вы это сделали без Qt только на C++? Только идея интересует. boost:signals, собственный велосипед или еще что-то.

Вроде всё правильно, сами на свой вопрос и ответили Улыбающийся. Считаю, что паттерн применяется по назначению, а его реализацию выбирайте ту, которая лучше всего подходит для вашего проекта. Если уже используется boost, то, возможно, и нет причин отказываться от boost:signals. Есть и другие библиотеки, которые реализуют "сигнал-слот". Если совсем всё глобально, может и свой велосипед написать стоит.

Также интересны ответы в случае, когда файл в структуру грузит функция C в dll, а прогрессбар должен меняться в приложении C#, например.

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

Просто понял, что меня бы подобная задача озадачила бы слегка. Коряво, сделал бы, но интересно как это сделают гуру.

Если задача озадачивает лишь слегка, значит есть силы самостоятельно её решить Улыбающийся.
Записан

Пока сам не сделаешь...
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #3 : Апрель 07, 2016, 11:41 »

Вариантов решения масса, все зависит от дополнительных требований.

1. Синхронная или асинхронная работа компонентов (например, загрузчика и графического интерфейса).
2. Событийная или распределенная модель обмена данными.
3. Модульность

Эти требования определяют выбор паттерна, который целесообразно использовать.

Синхронность/асинхронность определяется однопоточностью или многопоточностью программы.
Событийность предполагает передачу событий в виде данных или их копии (события/сообщения/данные сигналов) актуальной на момент события. Распределенная модель может подразумевать доступ к распределенным данным, актуальным на момент обращения к ним, а не на момент события.
Модульность - следствие личного опыта и требований к легкости дальнейшей модификации и сопровождения ПО.

Самый простой и быстрый вариант (с нуля) - синхронная событийная модель, которая в зависимости от необходимой модульности (возможной "вязкости" кода) может быть сведена:
- к явным вызовам API одного компонента из другого (подавляющее число реализаций, плохо сопровождаемый код),
- к модели наблюдателя (подписка на события, уже лучше),
- к модели сигнал-слот boost, Qt (взаимосвязь независимых модулей, еще лучше),
- к чему-те еще

Все варианты правильные, выбор зависит от разработчика (его опыта) и решаемой задачи.

Если задача комплексная (например, загрузка файлов мешает отображению GUI и/или наоборот), то необходимо уже смотреть в сторону асинхронной модели поведения

- асинхронный сигнал слот
- модель актеров
- активные объекты
- что-то еще

выбор за Вами ...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Апрель 07, 2016, 12:43 »

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

Вместо упора на "священную корову" слот/сигнала лучше тщательнее продумать интерфейс (что должен получать индикатор), там не так уж мало данных
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Апрель 07, 2016, 13:10 »

Принципиально важна независимость от реализации индикатора, это легко обеспечить.
Это сейчас ТС хочет просто показать индикатор выполнения, а завтра ему понадобиться эти файлы патчить в процессе загрузки.
Сядем и придумаем еще один интерфейс для этого или сразу подумаем и сделаем универсально?
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #6 : Апрель 08, 2016, 08:25 »

А что тут "еще лучше"? Улыбающийся ...
Вместо упора на "священную корову" слот/сигнала лучше тщательнее продумать интерфейс (что должен получать индикатор), там не так уж мало данных

Как раз сигнал слот не священен Подмигивающий Это просто более гибкий механизм взаимодействия, чем паттерн наблюдателя, так как не требует прямых или косвенных взаимосвязей между типами объектов, участвующих во взаимодействии.
Если говорить о реализации сигнал-слот взаимодействия в Qt, то наследование от QObject - ооочень неудачное решение), но это всего лишь одна из возможных.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Апрель 08, 2016, 10:34 »

Принципиально важна независимость от реализации индикатора, это легко обеспечить.
Это сейчас ТС хочет просто показать индикатор выполнения, а завтра ему понадобиться эти файлы патчить в процессе загрузки.
Сядем и придумаем еще один интерфейс для этого или сразу подумаем и сделаем универсально?


https://en.wikipedia.org/wiki/You_aren't_gonna_need_it

Я тоже не вижу, для чего тут нужен обсервер. Подхода Игоря вполне достаточно.
« Последнее редактирование: Апрель 08, 2016, 10:36 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Апрель 08, 2016, 10:43 »

Я тоже не вижу, для чего тут нужен обсервер. Подхода Игоря вполне достаточно.
А что вы подразумеваете под обсервером?
В контексте этого обсуждения "обсервером" может быть просто вызов сигнала.
Я только предложил не затачивать его интерфейс только для индикации процесса выполнения, а продумать более универсальное решение. Что сделать совсем не сложно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Апрель 08, 2016, 10:52 »

Хорошо, пусть нет никаких ограничений на использование Qt и/или буста, используйте что хотите (если в этом счастье). Но вот индикатор нужен "мульти" (этажерка из 2 и более бегунков по вертикали). Это типовая вещь, масса приложений (начиная с самого OC) такие индикаторы делает.

Ваши действия? (кроме поисков "готового решения")
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Апрель 08, 2016, 11:05 »

Хорошо, пусть нет никаких ограничений на использование Qt и/или буста, используйте что хотите (если в этом счастье). Но вот индикатор нужен "мульти" (этажерка из 2 и более бегунков по вертикали). Это типовая вещь, масса приложений (начиная с самого OC) такие индикаторы делает.

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

А реализовать диалог с двумя progressbar совсем не сложно.
В начале загрузки загрузчик посылает сигнал, где сообщает общий размер всех файлов и их количество.
Дальше запускается загрузка файлов. В начале загрузки каждого файла загрузчик посылает сигнал с именем файла, его порядковым номером и размером, а в процессе загрузки периодически посылается сигнал о прогрессе его загрузки.
При завершении загрузки каждого файла, посылается сигнал о завершении с передачей его имени и порядкового номера.

Этого достаточно для вышеописанной задачи, а также становится доступно выводить прогресс не по размеру, а по целым файлам.
« Последнее редактирование: Апрель 08, 2016, 11:14 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 08, 2016, 12:17 »

...загрузчик посылает сигнал, где сообщает ..
..загрузчик посылает сигнал с именем файла, ...
..периодически посылается сигнал о прогрессе ..
...посылается сигнал о завершении ..
Типа "главное - сигнал (залог успеха)". А по мне его роль здесь очень скромная - ну разве что "развязаться" из др нитки, т.е. "обертка", не более того. И чего это "двумя" (progressbar)? А для 3 что, "сядем придумаем еще сигналы"? Зачем завязываться на то что второй - суб-процесс первого? Это может быть напр независимое параллельное копирование (или зипирование) файлов/фолдеров,

Поэтому вместо беготни с сигналами лучше заняться выделением тех самых "сущностей". Напр я четко вижу сущность "индикатор" (бегунок) которых может быть 2 и более. Но заниматься этим никто не хочет. Вот хапнуть готовый класс, переписать примерчик - то да! А остальное - так себе, "свой велосипед" Улыбающийся
Записан
Bepec
Гость
« Ответ #12 : Апрель 08, 2016, 12:23 »

Бгг, Igors в своём репертуаре. Давайте вместо передачи 4 байт информации напишем класс индикатора, ползунка, индикатора-ползунка, контейнер общий для них и вариативность постройки диалога вплоть до 256 индикаторных ползунков.

Ну и что, что нужно будет максимум 3-5, зато получится идеально, хотяяя... а вдруг ещё ползунковый цветовой информатор с обратной связью нужен будет Веселый
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Апрель 08, 2016, 12:34 »

Типа "главное - сигнал (залог успеха)".
Вовсе нет. Сигнал здесь это способ информирования других объектов о изменении состояния текущего. Не более.
Как этот "сигнал" будет реализован дело 10 и совершенно не интересное. Это могут быть сигналы Qt или буста, а может сигналы DBus или обычная std::function, а может это будет объект класса Listener...

А по мне его роль здесь очень скромная - ну разве что "развязаться" из др нитки, т.е. "обертка", не более того.
Точно.

И чего это "двумя" (progressbar)? А для 3 что, "сядем придумаем еще сигналы"? Зачем завязываться на то что второй - суб-процесс первого? Это может быть напр независимое параллельное копирование (или зипирование) файлов/фолдеров,
А я не на что и не завязывался. Вы захотели два progressbar - с моими сигналами это легко сделать, захочет человек один бар по общему размеру - легко, захочет по количеству файлов - пожалуйста. А может он захочет патчить или проверять загруженные данные совместно с отображение прогресса - ну так сколько угодно.

Поэтому вместо беготни с сигналами лучше заняться выделением тех самых "сущностей". Напр я четко вижу сущность "индикатор" (бегунок) которых может быть 2 и более. Но заниматься этим никто не хочет. Вот хапнуть готовый класс, переписать примерчик - то да! А остальное - так себе, "свой велосипед" Улыбающийся
Четко видите сущность индикатор? А мне он сейчас не нужен. Я не хочу показывать прогресс выполнения, а хочу рассчитывать и отображать контрольные суммы загруженных файлов.... В каком месте мне эту "четко видимую сущность" нужно использовать? Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Апрель 08, 2016, 13:52 »

Вы захотели два progressbar - с моими сигналами это легко сделать, захочет человек один бар по общему размеру - легко, захочет по количеству файлов - пожалуйста.
Та неужели? Вот Вы сказали магическое слово "сигнал", и, о чудо, весь ф-ционал волшебным образом появился!! Наверное так работают "Ваши" сигналы, о которых мне ничего не известно  Улыбающийся
Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.193 секунд. Запросов: 22.