"event" какъв му е смисъла?


1
Пиша си домашните , та вече минахме event-ите. Но така и не разбрах , защо трябва да има такъв обект "еvent"?
  Ако имам Timed Event мога да си пусна Делегат през new Thread , a пък ако следя нещо да се случи , то имам чувството че почти винаги ще искам да контролирам complexity-то на проверката и точно къде , кога и как се случва. Примерно ако искам да следя дали Героят Health-a не му е <= 0 , то просто в seter-а ще си правя проверката и там бих си Invoke-нал делегата/делегатите.
  Длъжен ли съм да ползвам "event" и ако не го ползвам какво губя?

  Благодаря!



Отговори



3

Една задача може да се реши по много различни начини. Системата на евънтите ти предлага удобство, което отгоре на това е унифицрано и се ползва на много места. Ако почнеш да пишеш примерно някакво десктоп приложение, ще видиш колко благинки може да ти донесе този подход.

Дори и да не знаеш как работи останалата част от кода, можеш просто да се "абонираш" за някакво събитие и ще бъдеш уведомен когато то настъпи. В същата нишка, в друга - няма голямо значение. Можеш да се абонираш на 20 места за едно и също събитие, можеш да се отписваш ако вече не те интересува...

Пиша си тука една програмка на WPF... имам един комбобокс с който потребителя може да променя дименсиите от метри в сантиметри или в милиметри. В момента в който комбобокса си промени стойността, всички места където досега е имало въведени стойности се преизчисляват и се показват числа във верните единици. А в модела ми се пазят стойности в унифицирани дименсии, в които трябва да се извършват изчисленията.
И това почти без писане на код - един MultiValueConverter от 5 реда и съответно MultiBinding в XAML-а там, където е необходимо. Това става благодарение на мощната система от евънти, която навързва всичко във WPF-а.

Примерно имам число, което отразява координатата X на нещо. Имам обект "точка" която има полета X и Y, Имам правоъгълник, който се описва като 2 точки - двата противоположни ъгъла. За тоя правоъгълник ми трябват неговата площ, неговия периметър и т.н.

Потребителя от UI променя координатата Х на някаква точка - едно число. Чрез система от евънти аз уведомявам точката, която е "собственик" на тази координата, че се е преместила. Тя от своя страна уведомява правоъгълника, че е настъпила промяна в координатите на единия му ъгъл, което извиква методи за преизчисляване на площта и периметъра му. Самия правоъгълник пък вече уведомява модела, че се е променил и се правят проверки дали не се покрива или застъпва с другите правоъгълници... 

Всичко това става по един унифициран начин, като във всеки един обект по веригата имам пълен контрол върху случващото се, както и запазвам почти пълен decoupling на обектите - всеки е сам за себе си, не е вързан с другите по веригата нагоре и надолу.  Ако някой го интересува че дадена точка е променена - интересува го и бива уведомен. Ако никой не се интересува - пак същия код се ползва.

Същата тая точка мога да я ползвам и като център на окръжност обаче. Без промяна и на ред код. Новия обект Кръг ще прилича изключително много на обекта Правоъгълник. Точката ще работи отново по същия начин. Ще мога да се абонирам за събития променящи както правоъгълника, така и кръга, по един и същ начин.


от JulianG (5316 точки)


0
Ахаа , тоест ако обекта ми не е bind-нат към делегата чрез някакъв обект , ще ми се налага винаги да подавам референция за него към всеки Subscriber , който пък да има логика за отписване или да управлявам нещата само от scope-а където стои този делегат.
  Ще ми се спъне ООП-то и язък че съм разделил всичко на обекти , правилно ли съм разбрал? :)

от Betastate (341 точки)

1

В моя пример си представи ,че точката която е ъгъл на правоъгълника, иска да го уведоми че е променена. Какъв делегат ще подаде точката към правоъгълника, при условие че по дефиниция тя не трябва да знае нищо за него (щото може да е ъгъл на правоъгълник, но и център на окръжност)?

А не е работа на правоъгълника да си следи точките. Той иска да бъде уведомен ако някоя се промени, и той трябва да предприеме някакви действия, а не точката.

Да, можеш при инициализацията на точката да й дадеш делегат в зависимост от това дали го играе ъгъл или център. Обаче той дефакто е код от правоъгълника, не е работа на точката да "си играе с играчките на висшестоящия".

Много по-логично е "подчинената" точка да "позвъни на шефа си" като една добра секретарка и да му съобщи "Шефе, докат те нямаше те търси Гошо, каза че има 10 тона зеле по 60 стинки килото" и шефа да решава ще го купува ли, колко ще купува, дали изобщо ще звъни на Гошо да говорят за цената...

А в твоя случай излиза че шефа излизайки дава на секретарката заръка "ако някой звънне и каже, че продава зеле по 60 стинки или по-малко - е ти ключа от касата, извади пари и го купувай". Не че няма да работи, не че няма практика така да се процедира, но ... логиката е счупена малко, нали? :)


от JulianG (5316 точки)


1

"Топло, топло", Бетастейт.... но само частично. Както е казано ТУК, програмите за обработка на (значителни) събития  - (significant) event handlers, се извикват с помощта на делегати. Възникването на събитие предизвиква т.нар. "заявка за прекъсване" (interrupt request) към операционната система и тя предава управлението на съответния event handler. Системата за прекъсвания и обработката на събития са основни съставни части на операционните системи и Юлиан много подробно ти е обяснил за какво се използват като мощно средство за създаване на интерактивни програми, а също така за мониторинг и управление на процеси в реално време. Освен софтуерните прекъсвания, които се обработват по софтуерен начин, има и хардуерни прекъсвания, най-често при комуникация с външни (периферни) устройства - диск, принтер, мрежа и т.н., които се осъществяват с висока скорост и по никакъв начин не натоварват процесора - това е прозрачно за програмиста и не е необходимо да се грижи, когато разработва приложението си.

Делегатите обаче можеш да използваш много ефективно и в следния случай:

Представи си, че в зависимост от някакви параметри или условия искаш програмата ти да изпълни една от няколко функции. Тогава използваш делегати. Все едно, че имаш масив от референции към адресите на функции. Това придава голяма гъвкавост на кода и общо взето, е много яко :)


от ellapt (6303 точки)


1
Благодаря за подробния отговор!

Ще гледам още няколко Tutorial-а и ще се пробвам да смеля синтаксиса наново :)

Няма по-красиво от това нещата да се случват в хардуер или поне по-близко до метала.

от Betastate (341 точки)