Interfaces vs. callbacks

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8218
+
0
-

Otázka: proč je Translator/Authenticator/Authorizator/PermissionAssertion/Mailer/PresenterLoader interface a ne callback? Nebo proč se naopak nepoužívá interface ITemplateFilter/ITemplateHelper?

Jaký je vlastně rozdíl mezi interface a callback? Připadá mi, že interface je objektový přístup, protože jeho středobodem je objekt, zatímco callback je funkcionální přístup, protože jej zajímají čistě „funkce“.

Jaké rysy má použití interface:

  • máme přístup k více metodám objektu
  • lze také zjistit, zda objekt implementuje další interface (= další metody)
  • zřejmá deklarace parametrů metody a PHP je ověřuje
  • vyjadřuje vazby mezi třídami
  • volání je rychlejší

Callback se zase vyznačuje:

  • lze jej vytvořit ke každé metodě, naopak s interface musí třída počítat
  • jako callback lze použít statické metody nebo funkce
  • od PHP 5.3 lze zapisovat použít lambda funkce, v Nette podpora via fci callback()
  • může být z pohledu programátora jednodušší

Případy uvedené v úvodní otázce lze implementovat jak přes interface, tak přes callback. A to proto, že a) rozhraní mají právě jednu metodu a b) s objektem se nedělá nic jiného, než že se na něm ona metoda volá. Pro takové případy by mělo existovat vodítko, jestli jít cestou interface nebo callback.

Vodítkem by mohly být otázky:

  • může se implementace rozšířit tak, že bychom potřebovali nad předaným objektem volat více metod nebo použít operátor instanceof a tedy callback by nedostačoval?
  • nebo je naopak výhodné mít možnost odvolávat se na statické metody nebo funkce (nativní, lambda) a interface by situaci komplikoval?
  • je striktnější deklarace a kontrola parametrů volané metody výhodou nebo nevýhodou?
  • představuje použití jednoho nebo druhého řešení zbytečný nárůst kódu?

Z uvedených otázek celkem jasně vychází, že případný ITemplateHelper by byl vyloženě kontraproduktivní, ITemplateFilter by už měl určité opodstatnění, IAuthenticator, IAuthorizator a IMailer jsou jako rozhraní zvoleny dobře, naopak IPermissionAssertion by se lépe hodilo implementovat skrze callback.

redhead
Člen | 1313
+
0
-

Kde jsou logické, tak interfaces. A musím spíš říct co nejmíň callbacků, myslím, že běh skriptu zatěžují víc než interfacy (kór když by měli striktně kontrolat parametry atd..). Ostatně poslední odstavec je právě to nejlepší řešení..

pekelnik
Člen | 462
+
0
-

+1

v6ak
Člen | 206
+
0
-

V PHP mi přijdou v takovémto případě ty interfaces zbytečné (nutnost vytvářet třídu), vemte si navíc situaci, kdy té třídě chci něco předat! Pro PHP neznám nic jako Lombok, takže se musí přidat privátní vlastnost, parametr konstruktoru a přiřazení – celkem otrava. Jo, a ještě to předat.

„myslím, že běh skriptu zatěžují víc než interfacy (kór když by měli striktně kontrolat parametry atd..).“
Já bych řekl, že to bude spíš naopak, ale neměřil bych to.

Jinak ve chvíli, kdy má být něco vráceno, bych nad objektovým typem až tak neváhal, ale pokud jde o registrování handlerů, tak mi tu přijdou callbacky přívětivější.