crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Получается монстр, (о сигналах и слотах)
Анна
  опции профиля:
сообщение 30.11.2018, 17:27
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 276
Регистрация: 22.5.2008
Из: Зеленоград
Пользователь №: 181

Спасибо сказали: 30 раз(а)




Репутация:   4  


Есть у меня огромная структура, которая представляет из себя внутренности некоторого устройства.
Изначально требовалось приложение, которое скачивает в эту структуру из устройства значения, что-то меняет, записывает обратно.
Потом появилась надобность в другом приложении, пользующемся этой же структурой, потом ещё одно приложение...

В результате у меня родился класс, который обслуживает эту структуру по принципу "мне нужно такое-то значение" - "на тебе это значение", и т.п. - то есть куча сигналов и слотов.

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

class Interface
{
...
   void setManager(Manager *m) {m_manager = m;};
   void foo1();
   void foo2()
...
   Manager *m_manager;
};

Interfase::foo1()
{
   m_manager->setValueA(val);
}

Interface::foo2()
{
   int val = m_manager->valueA();
}



у меня получились :

class Interface
{
...
   void foo1();
public slot:
   void foo2(int);

signal:
   void valueARequired(); // интерфейсу требуется значение A
   void valueAChanged(int); // интерфейс изменил значение A

...
};


void Intreface::foo1()
{
...
   emit valueAChanged(val);
}

Interface::foo2(int a)
{
   int val = a;
...
}


Ну, и, конечно же, есть в главном окне штабеля коннектов:

connect(interface, SIGNAL(valueAChanged(int)), manager, SLOT(setValueA(int))); 
connect(interface, SIGNAL(valueAChanged(int)), manager, SLOT(setValueA(int)));
connect(manager, SIGNAL(valueAChanged(int)), interface, SLOT(foo2(int)));
...


Классов типа Interface несколько (они абсолютно разные. Среди них есть и QWidget и QObject), каждому нужны различные значения из структуры, спрятанной в Manager, каждый хочет какие-то поля менять и получать уведомления об изменениях.
Мне вот интересно, это нормально нормальный подход к решению - всё решать через сигнал-слот, или нужно всё-таки делать гибрид, когда есть и обращение к менеджеру через указатель и с помощью сигналов, слотов и connect()? И, вообще, когда какое решение лучше применять? По ходу, получается паттерн Наблюдатель, но только оба класса являются взаимными Наблюдателями.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 1.12.2018, 7:24
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2885
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Анна, лично я вообще не пользуюсь сигналами и слотами кроме тех, которые уже есть в классах Qt :) То есть, не ввожу новых

И всё прекрасно получается.

В твоём случае контейнер всех элементов можно сделать глобальным (учесть синхронизацию доступа, если имеется многопоточность). И пусть кто угодно и где угодно пишет и читает без слотов. А уведомления можно оставить сигналами, либо свою очередь уведомлений сделать

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 18.8.2019, 19:58