Pull to refresh

Comments 35

Мне кажется Rx библиотека более гибкая в использовании чем сигналы и слоты. Как реализовывать на сигналах ситуацию: doSomething() только после того, как получены два сигнала? Придется пилить свой велосипед, который опять таки станет Rx
Никак и не реализовать такое поведение на сигналах. Хм. Можете привести реальный пример, когда такое поведение необходимо?
Например после двух запросов к бд (за новостями и комментариями к ним). по отдельности они нас не интересуют, а вот если вместе — то записать в лог/внести подозрительный ip в бд
И релизовать можно. Через посредника, который подпишется на оба сигнала, и при их получении выдаст третий, на который уже подпишется целевой слот. но опять таки, уж лучше Rx делать. Тем более что он поддерживает асинхронную работу.
Верно. Поспешил я с ответом.
Мне видится несколько неудобным abstract class Signal. Я бы еще понял, если MeowSignal extends Signal, а с предлагаемым способом использования это выглядит странно: логгер в примере вынужденно «является» сингалом (is-a relation), хотя по сути то это не так; да и что делать, если у меня уже есть иерархия наследования? Может, в Qt оно так и сделано (хотя не знаю, не видел), но в С++ есть множественное наследование ведь.

Думаю, было бы уместнее либо трейт, либо Signal::emit() (либо оба варианта).
Действительно. Если иерархия уже имеется, то абстрактный класс не очень удобен. С трейтом идея нравится.
Банально в случае, если отнаследовался от сторонней библиотеки.
по сути Signal класс должен называться Signalable, тогда проблема с восприятием отойдет. Но так только интерфейсы принято именовать. Поэтому оставил Signal. Наверное, самый верный вариант в моем случае — это трейт.

И в Qt сделано не так, не надо плохо о нем думать)
Зато Signalable — отличное имя для трейта, как писали выше ;)
Переписал на трейте. Обновлен пункт 1
В composer.json еще забыли версию php поменять. Трейты доступны начиная с 5.4.
ИМХО, механизм сигналов и слотов сам по себе хорош, но что касаемо данного примера… я не могу сказать, что меня это вдохновило, извините. Сигнатура
ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');

Меня немного смущает… Довольно простой пример, и в нем уже такая простыня… а если задачи усложнятся по тем вариантам, которые вы привели?
  • Один сигнал к нескольким слотам
  • Несколько сигналов к нескольким слотам
  • Несколько сигналов к одному слоту

И как мне установить в одном соединении несколько ресиверов? К примеру я создал 3 класса Receiver1. Receiver2, Receiver3 и заимлиментился от Receiveable который реализовал slotReactOnSignal(). Далее, я хочу сделать так:
ConnectionManager::connect($logger, 'somethingIsLogged', [$receiver1, $receiver2, $receiver3], 'slotReactOnSignal');

А если добавить в эту логику внутреннее общение между слотами…
Как мне видится, я полностью согласен с webmasterx все придет к тому, что нужен Rx.
Не хочу сказать, что она бесполезная, я просто не вижу область применений) А не можете дополнить статью еще какими-либо примерами? )) Чтобы ощутить полезность вашей библиотеки) Хотелось бы ее использовать, но где ее юзануть так, чтобы она была прям полезной…
Эта сигнатура пришла исключительно из Qt и мне тоже не нравится. Но зато она знакома Qt кодерам. А для нескольких ресиверов нужно просто повторить
ConnectionManager::connect($logger, 'somethingIsLogged', $receiver, 'slotReactOnSignal');

И пременения я тоже не нашел. В Yii2 можно подключиться к событиям модели, думаю и к другим классам тоже, и в других фреймворках тоже найдется аналог.
Но в итоге если нужна событийная реализация — приходим к тому же Rx.

ИМХО: сигналы и слоты в Qt либо пережиток прошлого (не догадались до абстракции Rx), либо умышленное упрощение в сторону скорости.
По поводу сигнатуры. Что в ней такого страшного? Вроде бы все логично и интуитивно понятно: сигнал от отправителя соединяется со слотом получателя.

По поводу соединений — посмотрите тесты. Как указал webmasterx будет несколько последовательных вызовов ConnectionManager::connect().

По поводу применения. Вначале статьи я писал, что сигналы и слоты отлично подходят для gui приложений с event loop. Там они смотрятся на своем месте. Что же касается реального применения в скриптовом php: сигалы и слоты можно использовать там, где подходит наблюдатель. Например выполнить действие перед сохранением сущности. Или же (о боже мой максимализм) переписать старый процедурный подход в приложении с хуков на сигналы.

Вообще, конечно же, just for fun. Узнал как пишутся composer пакеты.
UFO just landed and posted this here
Угодили. Спортивный интерес. Ваш вопрос можно задать и относительно к evenement/evenement
UFO just landed and posted this here
Это ведь реализация шаблона «Медиатор». Я вот только что осознал, что сигналы и слоты — больше «Медиатор», чем «Наблюдатель». Так как возможны соединения не только один к одному, но и многие ко многим.
Спасибо, не видел. Подход почти такой же. С одним различием, что там классический «Наблюдатель», где наблюдаемый объект содержит в себе список всех наблюдателей. В сигналах и слотах маппинг объект.сигнал -> объект.слот не хранится в наблюдаемом объекте.

Очень похожа) И судя по всему очень популярна. Ну, хотя бы мой спортивный интерес удовлетворен.
UFO just landed and posted this here
Мой комментарий был по поводу evenement/evenement, которая является классической реализацией шаблона «Наблюдатель». В этой библиотеке все наблюдатели хранятся внутри наблюдаемого объекта, а не в диспетчере. Посмотрите реализацию.

Про диспетчер Вы, наверное, имели в виду symfony event dispatcher. Там согласен, маппинг объект.сигнал -> объект.слот хранится в диспетчере.
evenement/evenement все же не классическая реализация наблюдателя. все же наблюдатели привязываются к событию. но суть та же.
UFO just landed and posted this here
ответ простой — для наглядности. У Вас в классе может быть множество методов и лишь для того, чтобы среди этого множества выделить те методы, которые могут использоваться в качестве слотов, используется «ключевое» слово «slot». Не более. Конечно, технически в этом никакой необходимости нету.
Вы, в общем-то, правы. Убрал ограничение на именование слотов.
штука чисто для фанатов сигналов и слотов — для людей которые писали на Qt и хотят похожего поведения.

ну а для нормальных людей есть привычные «события» удобно использовать, читабельный код — просто и понятно
Ну что Вы так сразу «ну а для нормальных людей». У Вас вон вообще, аватар — шоколадка)
UFO just landed and posted this here
Чем, кроме названия, это отличается от EventManager в ZF2 и аналогичного в Symfony?
По сути ничем. Еще одна реализация взаимодействия между объектами.
Для PHP механизм signal-slot не требуется, т.к. отсутствует потоковая модель (все функции и методы в PHP блокирующие) и необходимость между этими потоками общаться. А если вы при помощи данного механизма желаете навешивать некоторые стандарные поведения на группы объектов, то лучше использовать одноименный шаблон Behavior (поведение) — значительно красивее и понятнее получится.
Sign up to leave a comment.

Articles