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
ИМХО, механизм сигналов и слотов сам по себе хорош, но что касаемо данного примера… я не могу сказать, что меня это вдохновило, извините. Сигнатура
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
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