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: Событийно ориентированное программирование
От: 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
Событийно ориентированное программирование
От: _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[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: Событийно ориентированное программирование
От: 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[10]: Событийно ориентированное программирование
От: dimgel Россия https://github.com/dimgel
Дата: 22.07.14 07:55
Оценка: 1 (1)
Здравствуйте, ionoy, Вы писали:

I>в отличие от IDisposable.


SRP, кстати, опять же.
Re[2]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 06:51
Оценка: +1
Здравствуйте, os24ever, Вы писали:
O>Автор пишет, что это всего лишь Observer/Observable и был описан в книге GoF много лет тому назад.
O>Потому, наверное, так и сделано: "согласно положениям GoF".
Автор — поверхностный хам и воинствующее невежество. Он нашёл в Rx знакомое слово и из этого раздул целую статью.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
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: Событийно ориентированное программирование
От: 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[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[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[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>Пример кода, который вы хотите написать, в студию. С пояснением, почему вы не можете его написать в нынешнем коде.


Встяну. Вот лично у меня присутствует чисто психологический дискомфорт сохранять где-либо для последующей отписки ссылку на функцию. Оно конечно это можно списать на фантомные боли императивщика, но — а вдруг это замыкание какое, к примеру, тянущее за собой чёрт знает сколько захваченных данных?
Re[8]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 07:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


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

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

event EventHandler<bool> Event1;
event EventHandler<string> Event2;
        
public void Subscribe()
{
    EventHandler<bool> handler1 = (sender, b) => { };
    EventHandler<string> handler2 = (sender, s) => { };

    Event1 += handler1;
    Event2 += handler2;

    Unsubscribe(handler1, handler2);
}

private void Unsubscribe(EventHandler<bool> handler1, EventHandler<string> handler2)
{
    Event1 -= handler1;
    Event2 -= handler2;
}


В данном случае EventHandler<bool> и EventHandler<string> это конкретные типы обработчиков.
Я не могу написать:
void Unsubscribe(IEnumerable<EventHandler<T>> handlers) {
  foreach(var handler in handlers)
    //somehow unsubscribe?  
}

Потому что источники событий могут быть разные (Event1, Event2 и любая другая подписка).
Получается, что методу отписки нужно знать не только тип обработчика, но и само событие от которого нужно отписаться. Далеко не всегда есть возможность эту информацию предоставить.

S>Непонятно, почему именно Disposable.

S>Почему вы не хотите комбинировать, например, Action.
Из-за разных наборов параметров.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[9]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 07:51
Оценка:
Здравствуйте, ionoy, Вы писали:

S>>Непонятно, почему именно Disposable.

S>>Почему вы не хотите комбинировать, например, Action.
I>Из-за разных наборов параметров.

Дополню:
И необходимости передавать источник. От самого Action толку мало, в отличие от IDisposable.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[10]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 10:55
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Дополню:

I>И необходимости передавать источник. От самого Action толку мало, в отличие от IDisposable.
А, я, наверное, непонятно выразился.
вот что я имел в виду:
public Action Subscribe() {
  EventHandler<bool> handler1 = (sender, b) => { };
  EventHandler<string> handler2 = (sender, s) => { };

  Action unsubscribe = () => {
    Event1 -= handler1;
  };
  г
  return unsubscribe;
}

Как видим, внешнему коду вообще не нужно знать ни тип обработчика, ни конкретное событие. Достаточно позвать делегат, который ему вернули, в тот момент, когда вы хотели вызывать IDisposable.Dispose.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 11:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А, я, наверное, непонятно выразился.

S>вот что я имел в виду:
S>
S>public Action Subscribe() {
S>  EventHandler<bool> handler1 = (sender, b) => { };
S>  EventHandler<string> handler2 = (sender, s) => { };

S>  Action unsubscribe = () => {
S>    Event1 -= handler1;
S>  };
S>  г
S>  return unsubscribe;
S>}
S>

S>Как видим, внешнему коду вообще не нужно знать ни тип обработчика, ни конкретное событие. Достаточно позвать делегат, который ему вернули, в тот момент, когда вы хотели вызывать IDisposable.Dispose.

Примерно так оно и работает внутри. Есть, например, удобный метод:

Disposable.Create(() => Debug.WriteLine("Dispose called"));


Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

1. На основании этого интерфейса можно создать готовую библиотеку реализаций IDisposable, как сделали в Rx. Такие объекты предоставляют дополнительную функциональность для кода выдающего подписку, а для клиентов всё тот же IDisposable. Про некоторые готовые реализации опять же здесь: http://synchronicity-life.blogspot.com/2011/12/idisposable-implementations-in-reactive.html
2. IDisposable — это распространённый шаблон проектирования. Иногда бывает удобно локализовать подписку с помощью using.
3. IDisposable семантически лучше подходит на роль отписчика, чем Action
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[12]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 12:00
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Примерно так оно и работает внутри. Есть, например, удобный метод:


I>
I>Disposable.Create(() => Debug.WriteLine("Dispose called"));
I>


I>Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

Ну так и используйте его, если в вашей инфраструктуре он удобнее.
Лично мне более удобными кажутся weak events, т.к. сама необходимость следить за отпиской напрягает. Независимо от того, используется ли "честный" OnClick -=, Action, или IDisposable.
Я очень часто сталкивался с тем, что нам нужен "observer, который следит, покуда жив", а не "observer, который жив, покуда следит".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 22.07.14 14:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

I>>Как я это вижу, у IDisposable есть несколько преимуществ перед Action:

S>Ну так и используйте его, если в вашей инфраструктуре он удобнее.
S>Лично мне более удобными кажутся weak events, т.к. сама необходимость следить за отпиской напрягает. Независимо от того, используется ли "честный" OnClick -=, Action, или IDisposable.
S>Я очень часто сталкивался с тем, что нам нужен "observer, который следит, покуда жив", а не "observer, который жив, покуда следит".

Многие Observable так и устроены.

Например, такой код:
stream.Take(3).Subscribe(x => DoSomething(x))

сам отпишет подписчика. IDisposable нужен только в тех случаях, когда ты сам хочешь выбирать момент где переставать следить за потоком.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[14]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.07.14 17:54
Оценка:
Здравствуйте, ionoy, Вы писали:
I>сам отпишет подписчика.
Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Событийно ориентированное программирование
От: _NN_  
Дата: 23.07.14 03:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

Или в стиле шарпа:
void Resubscribe()
{
  Action myHandler = () => {};
  a.OnClick -= myHandler;
  a.OnClick += myHandler;
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Событийно ориентированное программирование
От: Jack128  
Дата: 23.07.14 06:20
Оценка:
Здравствуйте, _NN_, Вы писали:

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


_NN>В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

_NN>Или в стиле шарпа:
_NN>
_NN>void Resubscribe()
_NN>{
_NN>  Action myHandler = () => {};
_NN>  a.OnClick -= myHandler;
_NN>  a.OnClick += myHandler;
_NN>}
_NN>


а как ты такое в варианте с IDisposable реализуешь ?
Re[15]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 06:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

I>>сам отпишет подписчика.
S>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[8]: Событийно ориентированное программирование
От: _NN_  
Дата: 23.07.14 07:07
Оценка:
Здравствуйте, Jack128, Вы писали:

J>а как ты такое в варианте с IDisposable реализуешь ?


Например так:

IDisposable subscription;

void Resubscribe()
{
  subscription.Dispose();
  subscription = a.OnClick.Subscribe(myHandler);
}


Главное то, что я не смогу написать код, который якобы отписывается, а на деле ничего не делает.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[16]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 09:57
Оценка:
Здравствуйте, ionoy, Вы писали:
S>>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
I>Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
Что значит "по необходимости"? Как вы определите момент необходимости?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 10:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>>>Это понятно. Есть обратные ситуации — datasource.OnChange += form1.Refresh навсегда удержит форму в памяти.
I>>Так ведь можно отписаться по необходимости. Или я чего-то не понимаю?
S>Что значит "по необходимости"? Как вы определите момент необходимости?

Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной? Обычно момент удаления формы более или менее детерминирован.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[7]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 10:17
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>В том, что нельзя допустить вроде этой: http://www.rsdn.ru/forum/philosophy/5699473.1
Автор: _NN_
Дата: 19.07.14

_NN>Или в стиле шарпа:
_NN>
_NN>void Resubscribe()
_NN>{
_NN>  Action myHandler = () => {};
_NN>  a.OnClick -= myHandler;
_NN>  a.OnClick += myHandler;
_NN>}
_NN>

Ничего не понял. По ссылке — абсолютно работоспособный пример. На событие подписывается ровно одна функция.
В этом коде — тоже. На какой вопрос вы отвечаете — непонятно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 10:48
Оценка:
Здравствуйте, ionoy, Вы писали:
I>Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной?
Обычно (в среде с недетерминистической финализацией) объект перестаёт быть нужен тогда, когда последняя ссылка на него выходит из области видимости.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Событийно ориентированное программирование
От: Jack128  
Дата: 23.07.14 10:48
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Например так:


_NN>
_NN>IDisposable subscription;

_NN>void Resubscribe()
_NN>{
_NN>  subscription.Dispose();
_NN>  subscription = a.OnClick.Subscribe(myHandler);
_NN>}
_NN>


ну ты сохранил подписку в глобальной переменной. точно так же и лямбду можно сохранить. в чем отличие ?
Re[19]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 12:06
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

I>>Вопрос был в том, что привязка навсегда удержит форму в памяти. Если есть такая проблема, значит когда-то эта форма перестаёт быть нужной?
S>Обычно (в среде с недетерминистической финализацией) объект перестаёт быть нужен тогда, когда последняя ссылка на него выходит из области видимости.

Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае. Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[20]: Событийно ориентированное программирование
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.07.14 17:27
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае.

Да ладно!
Ещё как выходит. Если бы это было не так, то нам вообще бы не потребовался сборщик мусора — мы всегда бы знали, в какой момент пора звать деструктор и освобождать память

I>Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие

Да. С формой пример не совсем удачный, т.к. в ней есть явный Dispose, в котором можно сделать отписку и полагаться на компонентную модель в контроле времени жизни. И тем не менее — ошибку типа "забыл отписаться" сделать очень легко. Эта возможность граблей никуда не денется от того, что оператор += будет возвращать что-то другое. Нам всё равно нужно куда-то записывать ссылку, либо на IDisposable, который надо не забыть отдиспозить, либо на хэндлер, который нужно отписать.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Событийно ориентированное программирование
От: ionoy Эстония www.ammyui.com
Дата: 23.07.14 18:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


I>>Ссылка сама по себе не выходит из области видимости, какой-то код управляет этим процессом, в любом случае.

S>Да ладно!
S>Ещё как выходит. Если бы это было не так, то нам вообще бы не потребовался сборщик мусора — мы всегда бы знали, в какой момент пора звать деструктор и освобождать память
А можно пример, где ссылка сама по себе выходит из области видимости, но при этом остаётся в памяти из-за привязки к событию?

I>>Может просто пример с формой неудачный, т.к. там нет проблем отследить закрытие

S>Да. С формой пример не совсем удачный, т.к. в ней есть явный Dispose, в котором можно сделать отписку и полагаться на компонентную модель в контроле времени жизни. И тем не менее — ошибку типа "забыл отписаться" сделать очень легко. Эта возможность граблей никуда не денется от того, что оператор += будет возвращать что-то другое. Нам всё равно нужно куда-то записывать ссылку, либо на IDisposable, который надо не забыть отдиспозить, либо на хэндлер, который нужно отписать.
Это верно, ошибиться можно. Другое дело, что про эти грабли разве что глухой не слышал.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[10]: Событийно ориентированное программирование
От: _NN_  
Дата: 23.07.14 21:44
Оценка:
Здравствуйте, Jack128, Вы писали:

J>ну ты сохранил подписку в глобальной переменной. точно так же и лямбду можно сохранить. в чем отличие ?


Лямбду легко забыть сохранить и каждый раз создавать новую локальную переменную. Реальный баг
А вот объект подписки не сохранив не отпишешься.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Событийно ориентированное программирование
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.07.14 01:53
Оценка:
Здравствуйте, _NN_, Вы писали:

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


Хейльсберг. Он в добавок еще и с делегатами накосячил.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Событийно ориентированное программирование
От: landerhigh Пират  
Дата: 30.07.14 03:12
Оценка:
Здравствуйте, _NN_, Вы писали:

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

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

логически, вариант с

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


абсолютно эквивалентен

SomeEvent.Subscribe(MyHandler)
SomeEvent.Unsubscribe(MyHandler);


т.к. внутри себя объект "подписки" будет вызывать Unsubscribe. Оригинальный myHandler все равно где-то должен храниться.
Т.е. это не более чем синтаксический сахар, причем не самый удобный. Если хочется, его можно реализовать быстро, но фишка в том, что смысла особого нет.

Вариант с объектами-подписками означает, что подписки надо где-то хранить. Это автоматически влечет проблемы с подписчиками, желающими остаться инвариантами и/или подписываемые к более чем одному источнику. Причем, не стоит забывать, что очень часто, если не сказать "обычно", подписчик даже и не знает, что его подписали-отписали. В таких случаях явный

SubjectOne.Unsubscribe(Handler);
SubjectX.Unsubscribe(Handler);


очевидно предпочтительнее манипуляций с объектами-подписками, особенно если отписаться нужно не от всех источников.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.