Autor Zpráva
Amunak
Profil
Nedávno jsem narazil na skript pro zkracovače URL, yourls. Kód je procedurální. Zaujal mě tam způsob, jakým jsou řešeny pluginy. Konkrétně jejich volání a celkové zakomponování do systému. Přivedlo mě to na myšlenku, jak vlastně psát modulární kód správně? To co dělají v yourls vypadá asi takto:
/*** jádro ***/
//nějaký kód yourls
event_trigger('link_added', $link, $name, $id);
//další kód

/*** nějaký náhodný plugin ***/
event_register('link_added', function(){
  //kód náhodného pluginu - třeba vypíše nějakou vlastní hlášku, zaloguje akci, cokoliv
});

Nejprve se načtou soubory s pluginy, ty se (hádám) uloží do nějakého pole (asi by bylo vhodné tam nějak zakomponovat prioritu pluginů), a pak se při trigger_event zavolají. Takových triggerů je v kódu třeba i několik stovek, a přitom to není moc komplikovaná aplikace.

Moje otázky zní: Je tohle správný přístup? Šlo by to dělat lépe? Pomohlo by použití OOP? Tohle mi totiž přijde takové neohrabané. Fakt ale je, že je to docela funkční.

Jak by se to řešilo, kdybych chtěl nějakou událost zrušit? Rád bych totiž vytvořil aplikaci tak, aby byla modulární a daly se do ní snadno psát pluginy. Třeba jako Bukkit server API Minecraftu. Jenže to je Java (a té nerozumím dost na to, abych zkoumal, jak přesně mají pluginy řešené). Vím ale co to umí - prioritu spuštění událostí (vyšší se spouští poslední, nižší první), rušení událostí (třeba onBlockBreak jde zrušit, což způsobí, že se blok nevykope), detekci stavu události (je zrušená?), předat libovolné množství libovolných parametrů.

Rád bych se naučil jak správně napsat takový systém pro spouštění událostí a registraci pluginů. Hledal jsem taky nějaký srozumitelný článek na tohle téma, ale většinou to není popsané na PHP, i když tento princip funguje ve všech programovacích jazycích asi dost podobně.

Díky za odpovědi.
ShiraNai7
Profil
Amunak:

Šlo by to dělat lépe? Pomohlo by použití OOP?
Určitě by to šlo řešit čistěji pomocí OOP - nějakého event dispatcher komponentu, ale bylo by to to stejné v bledě modrém. Priorita a další pokročilá funkcionalita by určitě na škodu nebyla, ale asi ji autoři nepovažují za nutnou.

Je tohle správný přístup?
Jak k čemu. Rozšiřitelnost pomocí událostí je dobrý způsob, který ponechává volnost pro implementaci (stačí napojit listener/callback na událost). "Moduly" na úrovni aplikace bývají spíš konkrétní třídy extendující určitou základní anebo implementující rozhrání.
Amunak
Profil
ShiraNai7:
"Moduly" na úrovni aplikace bývají spíš konkrétní třídy extendující určitou základní anebo implementující rozhrání.
A jak pak takové moduly vypadají? Dokážu si představit, že pro nejzákladnější funkce by byla napsaná alespoň nějaká rozhraní, aby se trochu unifikovaly tyto základní moduly a aby bylo z čeho vycházet. Třeba modul pro přihlášení a práci s uživatelem by měl vycházet z rozhraní kde se používá nějaké ID uživatele, ověřovací klíč, aplikace může vyžadovat taky třeba nějaký unikátní API klíč a podobně. Ale jestli se to pak implementuje jako klasická registrace s přihlášením nebo openID už je na tom kdo to píše. To se však nevylučuje se systémem událostí. Můžu mít jen nějakou kostru (framework), a jen funkce (nebo třídy) pro načítání modulů. A pomocí nich pak můžu postavit celou aplikaci. KAždý modul si může registrovat vlastní události, ostatní na ně mohou reagovat. Jen nevím, jestli je to úplně vhodný postup. Jak zajistit, aby aplikace obsahovala nějaké závistlosti? Můžu mít třeba modul, co obsluhuje nějakou zaheslovanou sekci. Bude vyžadovat autentifikaci, ale nemám modul s přihlášením. Jak to pak vyřeším? Asi by si to měl řešit "nadřazený" modul - ten který zavolá stránku uvnitř zaheslované sekce, si taky pošle událost na modul který zpracovává tyto sekce, a ten pošle žádost (událost) o autentifikaci. Když se mu nic nevrátí, vyhodí výjimku.

Přemýšlím nad tím správně, nebo jsem úplně mimo?

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: