Событийно ориентированное программирование
От: _NN_  
Дата: 19.07.14 04:53
Оценка: 20 (3)
Кто знает почему сделали паттерн подписки и отписки от событий примерно так:

SomeEvent += MyHandler;
SomeEvent -= MyHandler;

SomeEvent.addEventListener(MyHandler);
SomeEvent.removeEventListener(MyHandler);


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

Эти мысли привели к более разумному применению как например в Rx, где подписка возвращает объект через который можно отписаться.
MySubscription = SomeEvent.Subscribe(MyHandler)
MySubscription.Dispose();


Даже в старом WinAPI был второй вариант.
Кто же все таки посчитал, что первый подход лучше ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Событийно ориентированное программирование
От: KARPOLAN Украина http://karpolan.com
Дата: 19.07.14 07:05
Оценка: -5
_NN>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события.
_NN>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.

Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера...
KARPOLAN (Anton Karpenko)
http://karpolan.com
http://facebook.com/karpolan
http://linkedin.com/in/karpolan
http://twitter.com/karpolan
http://plus.google.com/+AntonKarpenko
Re[2]: Событийно ориентированное программирование
От: _NN_  
Дата: 19.07.14 07:16
Оценка:
Здравствуйте, KARPOLAN, Вы писали:


_NN>>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события.

_NN>>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.

KAR>Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера...

Как не нужно ?
Вот в этом примере как отписаться ?
  window.addEventListener('click', function() {} );



Вот классическая ошибка первого варианта в JavaScript:

function f() {
  var handler = function() {    
  }

  // Удалить старое если было
  window.removeEventListener('click', f);
  // Добавить новое
  window.addEventListener('click', f);
}

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

Второй вариант также позволяет иметь более одного подписчика.
myEvent.Subscribe(f1);
myEvent.Subscribe(f2);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Событийно ориентированное программирование
От: KARPOLAN Украина http://karpolan.com
Дата: 19.07.14 07:23
Оценка: -7 :)
_NN>>>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события.
_NN>>>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.

KAR>>Не нужно ничего хранить, это глобальная константа. На ивент же может быть больше одного листенера...

_NN>Как не нужно ?
_NN>Вот в этом примере как отписаться ?
_NN>
_NN>  window.addEventListener('click', function() {} );
_NN>


'click' говоришь хранить надо? Ну ок, храни...
KARPOLAN (Anton Karpenko)
http://karpolan.com
http://facebook.com/karpolan
http://linkedin.com/in/karpolan
http://twitter.com/karpolan
http://plus.google.com/+AntonKarpenko
Re: Событийно ориентированное программирование
От: nikov США http://www.linkedin.com/in/nikov
Дата: 20.07.14 02:34
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Кто же все таки посчитал, что первый подход лучше ?


Я никогда не слышал, чтобы при дизайне C# 1.0 рассматривались другие варианты (анонимных функций тогда не было). Так что вполне возможно, что никто не решал, что выбранный подход лучше, это могло быть единственное решение, которое тогда пришло в голову дизайнерам. Хранить анонимные функции, конечно, неудобно, поэтому в Rx придумали другой подход. Но тебе всё равно нужно хранить объект, у которого ты собираешься вызывать Dispose() для отписки.
Re[2]: Событийно ориентированное программирование
От: _NN_  
Дата: 20.07.14 03:47
Оценка:
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, _NN_, Вы писали:


_NN>>Кто же все таки посчитал, что первый подход лучше ?


N>Я никогда не слышал, чтобы при дизайне C# 1.0 рассматривались другие варианты (анонимных функций тогда не было). Так что вполне возможно, что никто не решал, что выбранный подход лучше, это могло быть единственное решение, которое тогда пришло в голову дизайнерам. Хранить анонимные функции, конечно, неудобно, поэтому в Rx придумали другой подход. Но тебе всё равно нужно хранить объект, у которого ты собираешься вызывать Dispose() для отписки.


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

Как единственное решение ? На WinAPI не смотрели что ли
Образный код:
auto timer = SetTimer(myCallback);
KillTimer(timer);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Событийно ориентированное программирование
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 20.07.14 13:13
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В любом случае нужен какой-нибудь идентификатор для отписки.

_NN>Другое дело, что им почему-то является сам метод.
_NN>В таком варианте не всегда возможно подписаться в одном месте, а отписаться в другом.

_NN>Как единственное решение ? На WinAPI не смотрели что ли

_NN>Образный код:
_NN>
_NN>auto timer = SetTimer(myCallback);
_NN>KillTimer(timer);
_NN>


Это disposable объект для отписки, только в профиль.
Re: Событийно ориентированное программирование
От: Abyx Россия  
Дата: 20.07.14 15:23
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Кто знает почему сделали паттерн подписки и отписки от событий примерно так:


_NN>
_NN>SomeEvent += MyHandler;
_NN>SomeEvent -= MyHandler;

_NN>SomeEvent.addEventListener(MyHandler);
_NN>SomeEvent.removeEventListener(MyHandler);
_NN>


_NN>Тут ведь получается, что нужно хранить этот 'MyHandler' только для того, чтобы отписаться от события.

_NN>Т.е. его нельзя сделать анонимной функцией, локальной переменной и т.д.

_NN>Эти мысли привели к более разумному применению как например в Rx, где подписка возвращает объект через который можно отписаться.

_NN>
_NN>MySubscription = SomeEvent.Subscribe(MyHandler)
_NN>MySubscription.Dispose();
_NN>


_NN>Даже в старом WinAPI был второй вариант.

_NN>Кто же все таки посчитал, что первый подход лучше ?

SomeEvent.Subscribe можно сделать через +=/-=
C# не помню, по этому напишу на С++

function<void()> Subscribe(function<...> MyHandler) {
    SomeEvent += MyHandler;
    return [=]{ SomeEvent -= MyHandler; };
}


наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы,
чем использовать Subscribe с которым уже не сделать -=.
In Zen We Trust
Re[2]: Событийно ориентированное программирование
От: _NN_  
Дата: 20.07.14 18:41
Оценка:
Здравствуйте, Abyx, Вы писали:

A>наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы,

A>чем использовать Subscribe с которым уже не сделать -=.

Что значит сложнее ?
Да и проблема то какая решается ?

subscription1 = event.Subscribe(func1)
subscription2 = event.Subscribe(func2)

subscription2.Dispose(); // Отписались от 2
subscription1.Dispose(); // Отписались от 1
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Событийно ориентированное программирование
От: c-smile Канада http://terrainformatica.com
Дата: 20.07.14 21:50
Оценка: 5 (1)
Здравствуйте, _NN_, Вы писали:

_NN>Кто знает почему сделали паттерн подписки и отписки от событий примерно так:


Кто или где сделал?

В jquery (и Sciter) например так

var elem = ...

function handler(evt) { ... }

elem.on("click", handler); // 1
elem.on("click.mycls", function() {...}); // 2
elem.on("mouseup.mycls", function() {...}); // 3

elem.off( handler );   // отпишет №1
elem.off( ".mycls" );  // отпишет №2 и №3
elem.off( "click" );   // отпишет №1 и №2
Re[3]: Событийно ориентированное программирование
От: Abyx Россия  
Дата: 20.07.14 22:14
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Abyx, Вы писали:


A>>наоборот сделать уже сложнее, поэтому лучше использовать +=/-= с которыми можно использовать обе схемы,

A>>чем использовать Subscribe с которым уже не сделать -=.

_NN>Что значит сложнее ?

_NN>Да и проблема то какая решается ?

_NN>
_NN>subscription1 = event.Subscribe(func1)
_NN>subscription2 = event.Subscribe(func2)

_NN>subscription2.Dispose(); // Отписались от 2
_NN>subscription1.Dispose(); // Отписались от 1
_NN>


и кто и где должен хранить subscription?
In Zen We Trust
Re[4]: Событийно ориентированное программирование
От: _NN_  
Дата: 21.07.14 03:52
Оценка:
Здравствуйте, Abyx, Вы писали:

A>и кто и где должен хранить subscription?


Кто подписывается тот и хранит или передает дальше куда надо.
Разработчик волен делать что хочет.

С другой стороны не нужно знать про сам метод, чтобы подписаться.
Можно подписываясь передать приватный метод или анонимный, и отписаться можно извне без проблем.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Событийно ориентированное программирование
От: _NN_  
Дата: 21.07.14 04:03
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>
CS>var elem = ...

CS>function handler(evt) { ... }

CS>elem.on("click", handler); // 1
CS>elem.on("click.mycls", function() {...}); // 2
CS>elem.on("mouseup.mycls", function() {...}); // 3

CS>elem.off( handler );   // отпишет №1
CS>elem.off( ".mycls" );  // отпишет №2 и №3
CS>elem.off( "click" );   // отпишет №1 и №2
CS>


Я в jQuery не очень силен.
Как отписаться только от 2 или только от 3 ?

А как в jQuery работает возможность описаться от всех подписчиков ?
Т.е: $("someElement").off("click")
Неужели он хранит список всех, кто подписался.

P.S.
В RxJS например можно подписаться и отписаться вот так:
var keys = Rx.Observable.fromEvent(textInput, 'keyup');
var s = keys.subscribe(function() {});
s.dispose();
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Событийно ориентированное программирование
От: os24ever
Дата: 21.07.14 10:33
Оценка:
_NN>как например в Rx
Погуглил и нашёл: Just say No to “Reactive Programming”.
Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад.
Потому, наверное, так и сделано: "согласно положениям GoF".
Re[2]: Событийно ориентированное программирование
От: Abyx Россия  
Дата: 21.07.14 10:57
Оценка: 1 (1) +2
Здравствуйте, os24ever, Вы писали:

_NN>>как например в Rx

O>Погуглил и нашёл: Just say No to “Reactive Programming”.
O>Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад.
O>Потому, наверное, так и сделано: "согласно положениям GoF".

дааа, я помню этого парня!
http://stackoverflow.com/users/182669/dbjdbj

собственно там в комментах по ссылке написали
> Thats the worst example of BS and arrogance that I ever read online.
In Zen We Trust
Re[5]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 06:27
Оценка:
Здравствуйте, _NN_, Вы писали:
_NN>Можно подписываясь передать приватный метод или анонимный, и отписаться можно извне без проблем.
По-прежнему не очень понятно, в чём принципиальная разница между:

_myHandler = () => { };
a.OnClick =+ _myHandler;

...

a.OnClick -= _myHandler;

и
_myHandlerHandler = a.OnClick.Subscribe(() => { });

...

a.OnClick.Unsubscribe(_myHandlerHandler); // ну или _myHandlerHandler.Dispose();
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 06:51
Оценка: +1
Здравствуйте, os24ever, Вы писали:
O>Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад.
O>Потому, наверное, так и сделано: "согласно положениям GoF".
Автор — поверхностный хам и воинствующее невежество. Он нашёл в Rx знакомое слово и из этого раздул целую статью.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 07:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>По-прежнему не очень понятно, в чём принципиальная разница между:


S>
S>_myHandler = () => { };
S>a.OnClick =+ _myHandler;
S>a.OnClick -= _myHandler;

S>

S>и
S>
S>_myHandlerHandler = a.OnClick.Subscribe(() => { });
S>a.OnClick.Unsubscribe(_myHandlerHandler); // ну или _myHandlerHandler.Dispose();
S>


Удобнее тем, что внешнему коду не нужно знать конкретный тип обработчика, чтобы отменить операцию. Это значит, что мы можем использовать обобщённую логику отписки для разных "событий".
К тому же IDisposable можно комбинировать:


var disposable1 = stream.Subscribe(...);
var disposable2 = Disposable.Create(() => ...);

return new CompositeDisposable() { disposable1, disposable2 } //Возвращает IDisposable, который по очереди вызовет disposable1 и disposable2


Если интересно, то про разные реализации IDisposable можно почитать, например, тут: http://synchronicity-life.blogspot.com/2011/12/idisposable-implementations-in-reactive.html
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[7]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 07:34
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Удобнее тем, что внешнему коду не нужно знать конкретный тип обработчика, чтобы отменить операцию.

Что такое "конкретный тип обработчика"?

I>Это значит, что мы можем использовать обобщённую логику отписки для разных "событий".


Пример кода, который вы хотите написать, в студию. С пояснением, почему вы не можете его написать в нынешнем коде.

I>К тому же IDisposable можно комбинировать:


I>var disposable1 = stream.Subscribe(...);

I>var disposable2 = Disposable.Create(() => ...);

I>return new CompositeDisposable() { disposable1, disposable2 } //Возвращает IDisposable, который по очереди вызовет disposable1 и disposable2

I>[/c#]
Непонятно, почему именно Disposable.
Почему вы не хотите комбинировать, например, Action.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Событийно ориентированное программирование
От: dimgel Россия https://github.com/dimgel
Дата: 22.07.14 07:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Пример кода, который вы хотите написать, в студию. С пояснением, почему вы не можете его написать в нынешнем коде.


Встяну. Вот лично у меня присутствует чисто психологический дискомфорт сохранять где-либо для последующей отписки ссылку на функцию. Оно конечно это можно списать на фантомные боли императивщика, но — а вдруг это замыкание какое, к примеру, тянущее за собой чёрт знает сколько захваченных данных?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.