events versus collections & functies zelf aanroepen

Pagina: 1
Acties:

  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
Ik hoop dat ik dit onderwerp enigsizns duidelijk weet uit te leggen...

het gaat om het volgende: veel moderne talen laten het gebruik van events toe. in sommige gevallen is het overduidelijk wanneer events 'the way to go' zijn. Bijvoorbeeld in gui's. zelf gebruik ik ze echter niet zo vaak en kies ik voor een andere oplossing: een collectie met objecten die ik dan langsloop om een specifieke functie aan te roepen.

Om een voorbeeld te geven: ik heb in een toepassing een script mogelijkheid ingebouwd. dit project is in c#. een vereiste voor deze scripts is dat ze een run() functie hebben. je zou door middel van events dit kunnen afhandelen. ik heb er echter voor gekozen om ieder script (wat in feite gewoon een object is) te 'registreren' bij een script-host, wat inhoudt dat hij ze toevoegt aan de collectie. als het juiste moment daar is loopt de host de collectie af en roept van ieder object de run() functie aan.

nou geloof ik dat events nogal wat overhead opleveren (correct me if i'm wrong) dat is dus in dit geval een voordeel voor mijn methode. het nadeel van mijn methode is dat je moet gaan zitten boekhouden: je moet zelf bijhouden wanneer een script weggegooid moet worden.

ik heb hier een paar vragen over:
a) is mijn methode fout? zo ja, hou zouden jullie het doen?
b) wanneer is het wel slim om events te gebruiken?

  • Flard
  • Registratie: Februari 2001
  • Laatst online: 10:54
Het hangt natuurlijk een beetje van je taal af.

Nu geef je aan in C# te werken, in C# is een event in principe een gewoon een collectie van een events en zodra de event getriggerd wordt wordt gewoon in de collectie gekeken wat er allemaal uitgevoerd moet worden. Overhead is er dus niet echt.

In het geval van je script-host kan ik me echter wel een object met een run() functie voorstellen. Dat klopt semantisch gezien ook. Ieder script dient immers ook die run() functie te implementeren, aangezien hij zonder nutteloos is.
Het kan echter ook zo zijn dat je een object hebt wat verschillende 'events' heeft. Als het voor 'plugins' (of hoe je zo ook wel noemen) maar naar een aantal van deze events hoeven te luisteren, dan is het gebruik van Events juist beter want dan worden enkel de functies bij 'geabonneerde' objecten aanroepen, in tegenstelling tot jouw situatie, waarin dus ook objecten worden aangeroepen die helemaal niks met dat event doen. (dus onnodige overhead).

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Wat jij daar hebt lijkt verdacht veel op het Observer-pattern, wat niet veel anders is dan events ...

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
Flard schreef op dinsdag 13 februari 2007 @ 13:20:
Het hangt natuurlijk een beetje van je taal af.

Nu geef je aan in C# te werken, in C# is een event in principe een gewoon een collectie van een events en zodra de event getriggerd wordt wordt gewoon in de collectie gekeken wat er allemaal uitgevoerd moet worden. Overhead is er dus niet echt.
dus eigenlijk doet .net achter de schermen wat ik nu zelf doe?
In het geval van je script-host kan ik me echter wel een object met een run() functie voorstellen. Dat klopt semantisch gezien ook. Ieder script dient immers ook die run() functie te implementeren, aangezien hij zonder nutteloos is.
ze moeten ook inheriten van een abstracte klasse die alleen een run() een een dispose() heeft.
Het kan echter ook zo zijn dat je een object hebt wat verschillende 'events' heeft. Als het voor 'plugins' (of hoe je zo ook wel noemen) maar naar een aantal van deze events hoeven te luisteren, dan is het gebruik van Events juist beter want dan worden enkel de functies bij 'geabonneerde' objecten aanroepen, in tegenstelling tot jouw situatie, waarin dus ook objecten worden aangeroepen die helemaal niks met dat event doen. (dus onnodige overhead).
ik volg je niet helemaal 100%. bedoel je hiermee dat als de base class bijvoorbeeld functies heeft als run(), disable(), render(), donothing() (ik verzin maar wat) en deze functies niet voor ieder object van toepassing zijn (er is bijvoorbeeld een object waarin render() niet echt veel zin heeft omdat het niks rendert (weer even een loos voorbeeld)), dat je dan beter events kan gebruiken? dus dat je voor ieder object alleen de functies die van toepassing zijn als event registreert? daar kan ik me namelijk wel in vinden...
Wat jij daar hebt lijkt verdacht veel op het Observer-pattern, wat niet veel anders is dan events ...
wow. ik implementeer een patter, terwijl ik dus echt de ballen verstand daarvan heb :P

  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

Je kan ze in dit geval beter een interface laten implementeren dan van een abstracte klasse laten erven.

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • Flard
  • Registratie: Februari 2001
  • Laatst online: 10:54
st0p schreef op dinsdag 13 februari 2007 @ 13:38:
ik volg je niet helemaal 100%. bedoel je hiermee dat als de base class bijvoorbeeld functies heeft als run(), disable(), render(), donothing() (ik verzin maar wat) en deze functies niet voor ieder object van toepassing zijn (er is bijvoorbeeld een object waarin render() niet echt veel zin heeft omdat het niks rendert (weer even een loos voorbeeld)), dat je dan beter events kan gebruiken? dus dat je voor ieder object alleen de functies die van toepassing zijn als event registreert? daar kan ik me namelijk wel in vinden...
Ja, dat was in principe wat ik aan probeerde te geven.

Ik denk echter dat het met name te maken heeft met het type applicatie/klasse je wilt maken.

Stel je hebt een plugin-framework, dan verwacht je bijvoorbeeld dat iedere plugin een Install(), Uninstall(), en Process() heeft.
Zoiets kun je inderdaad (in mijn ogen) in interface (of abstracte klasse) vastleggen. Het gaat dan immers om een soort contract.

Maar stel je hebt plugins voor een gameserver (ik noem maar iets), dan is het in mijn ogen zinloos om in jouw interface ook nog functies PlayerJoined(), PlayerLeft(), en weet ik veel wat toe te voegen.
In dat geval kun je beter ergens in je Player-collection (die je toch al hebt) ook een event PlayerJoined en PlayerLeft toevoegen.
En in de Install() functie van de plugin dan bijvoorbeeld jouw eigen handler aan de PlayerJoined hangen. Volgens het 'contract' hoeft namelijk niet iedere plugin te reageren op een nieuwe player.
Op deze manier kun je, in dit voorbeeld, ook plugins volledig flexibel gebruiken.

Ik hoop dat ik het een beetje duidelijk heb gemaakt. Mijn punt is dus: als een functie volgens het 'contract' aangeboden moet worden, dan zou ik inderdaad met een interface en eigen collectie werken. In dat geval is bijvoorbeeld een run() functie ook geen event.
Maar als je dus niet weet wie het gaat gebruiken, en niet íedereen het hoeft te gebruiken zou ik voor een event-oplossing gaan.

Maar goed, het is dus ook een beetje een kwestie van gevoel. Voor mij althans.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Observer is een pattern dat de verantwoordelijkheid wanneer iets runt legt bij de observer: hij kijkt naar iets en als daar iets gebeurt, kan hij erop reageren.

Jij wilt plugins runnen op een gegeven moment M. Dan wil JIJ bepalen welke plugins. Dus het lijstje langsfietsen welke klaar zijn en runnable zijn, is een logische keuze.

Wil je het middels events oplossen dan zul je je plugin moeten vertellen welke events er zijn en dat deze dus subscribed aan die events.

Het gebruik van events hier is wat achterstevoren. Immers, bij het observer pattern (events) weet je niet wie er allemaal moeten runnen, en OF er iets moet runnen, dat boeit ook niet, jij vertelt gewoon dat iets gebeurd is. Bij een plugin systeem heb je dat juist niet. Je weet precies welke zaken moeten reageren op jouw call en dat zijn je plugins die in je queue staan. Dus het observer pattern is niet echt aan de orde, want je hebt niet echt het probleem dat je op tijdstip T niet weet wie allemaal moeten reageren op een event.

[ Voor 36% gewijzigd door EfBe op 13-02-2007 19:03 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

EfBe schreef op dinsdag 13 februari 2007 @ 18:57:
Het gebruik van events hier is wat achterstevoren. Immers, bij het observer pattern (events) weet je niet wie er allemaal moeten runnen, en OF er iets moet runnen, dat boeit ook niet, jij vertelt gewoon dat iets gebeurd is. Bij een plugin systeem heb je dat juist niet. Je weet precies welke zaken moeten reageren op jouw call en dat zijn je plugins die in je queue staan. Dus het observer pattern is niet echt aan de orde, want je hebt niet echt het probleem dat je op tijdstip T niet weet wie allemaal moeten reageren op een event.
Naar ik begrijp uit de TS is st0p helemaal niet geinteresseerd in of een observer/delegate/eventhandler/whatever runnable is op 't moment dat een event optreedt, hij wil gewoon de run() method van alle aangemelde clients aanroepen. Als dat 't geval is, is een delegate systeem handiger, omdat de host zich niet druk hoeft te maken over wat de subscribers met dat event doen, en of ze er iets mee doen.

Bij een plugin systeem waarbij het voor de hele applicatie van belang is dat bepaalde subscribers reageren (bv. een plugin die de GUI regelt (en die GUI essentieel is)) is 't handig om de host de regelneef te laten zijn, maar wanneer de subscribers toevoegingen zijn die leuk zijn voor die subscribers, maar de werking van de applicatie niet beinvloeden, is 't observer pattern m.i. een stuk beter. Dan belast je de host niet met dingen waar 'ie zich niet over hoort te bekommeren.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op dinsdag 13 februari 2007 @ 21:53:
[...]
Naar ik begrijp uit de TS is st0p helemaal niet geinteresseerd in of een observer/delegate/eventhandler/whatever runnable is op 't moment dat een event optreedt, hij wil gewoon de run() method van alle aangemelde clients aanroepen. Als dat 't geval is, is een delegate systeem handiger, omdat de host zich niet druk hoeft te maken over wat de subscribers met dat event doen, en of ze er iets mee doen.
Dat lijkt me niet, want hij wil de plugins runnen op tijdstip T, dus moet je de run method aanroepen, as simple as that. Je kunt wel een event gooien, maar je weet niet wat er dan gebeurt.
In het geval wanneer je dat niet erg vindt, DAN is observer goed. (vb. object geeft aan dat hij changed is, observers updaten hun state) Hier is dat wel erg, want je wil dat run wordt aangeroepen, dus roep je run aan.

Het is heel simpel: bij event oriented programming is de actie onbekend, alleen het tijdstip. Bij deze situatie is de actie bekend (run methods) en tijdstip ook. Dat is gewoon een call, hoe je het ook wend of keert. Immers, anders zou je ALLE calls in je applicatie middels events doen.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:54
Ik zie ook niet in waarom je hier events zou gebruiken, en EfBe slaat de nagel op de kop.
b) wanneer is het wel slim om events te gebruiken?
Events gebruik je om aan te geven dat er 'iets' gebeurd, zodanig dat diegene (de objecten) die daarin geinteresseerd zijn (en er dus op 'geabboneerd' zijn), er kunnen op reageren, op de manier waarop zij dat willen.

https://fgheysels.github.io/


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
hardstikke bedankt voor alle replies, dit heeft het voor mij wel een stuk helderder gemaakt!
Pagina: 1