Garant služeb
Jet zavádí termín garant služeb. Co to vlastně je? Začněme rovnou konkrétním příkladem logování v Jet (i když to celé se pochopitelně netýká pouze logování):
namespace JetApplicationModule\Content\Articles\Admin;
use Jet\Logger;
use Jet\MVC_Controller_Default;
class Controller_Main extends MVC_Controller_Default
{
public function add_Action(): void
{
//... ... ...
Logger::success(
event: 'article_created',
context_object_data: $article
);
//... ... ...
}
}
Ne, nelekejte se! Není to žádný service locator (například). A vše dává perfektní smysl. Čtěte dál ;-)
Obecně platí, že jakákoliv služba musí mít nějaké definované rozhraní (ať je to přímo rozhraní které implementuje, nebo abstraktní třída). Prostě a jednoduše uživatelé služby musí znát jaké má služba rozhraní a jak ji použít. To platí i zde. Logger v PHP Jet má rozhraní Jet\Logger_Interface (které je v tomto případě opravdu primitivní). V tomto ohledu se v PHP Jet vůbec nic nemění a pevně platí, že služby mají své dané rozhraní.
V jiných frameworcích však funguje to, čemu říkáme syndrom jedné velké hromady. O služby se stará již zmíněný komplexní subsystém. Služby jsou tak na jedné hromadě.
PHP Jet to dělá tak, že krom rozhraní služby systém definuje ještě garanta služby. Garant služeb není pouze statická fasáda, která je mostem do onoho velkého kontejneru služeb (jak to má jeden konkurenční framework). Ano, pohodlí a přímočarost použití fasády zde zůstává stejná. Ale garant služby v Jet není pouhá fasáda, ale zároveň i kontejner do kterého je vložen konkrétní poskytovatel služby.
Tedy pokud se budeme dále držet našeho příkladu s logováním, tak vězte, že ona fasáda Jet\Logger sama žádné logování neprovádí. Je to pouze garant služby - kontejner mající rozhraní reflektující danou službu, ale do toho kontejneru musel být vložen konkrétní poskytovatel služby (zde tedy logger, který již ví jak má danou operaci provést a službu poskytnout). Například takto:
Logger::setLogger( new Logger_Admin() );
Tedy při inicializaci aplikace na základě okolností (to je velice důležité) mohla nějaká vyšší autorita (zde inicializátor báze, ale může to být cokoliv jiného) rozhodla o tom jaká konkrétní služba bude použita pro logování.
Zde je tedy možné mít jiné logování pro administraci, jiné pro REST API, jiné pro web a tak dále. Zbytek aplikace to však nezajímá a prostě loguje - přesně tak jak v rámci DI pravidel má. Zároveň nenastává žádné peklo závislostí, žádné problémy. A použití všeho je naprosto jednoduché a přímočaré.
Méně kódu, méně složitostí, méně problémů. A zároveň i daleko větší flexibilita a lepší udržitelnost projektů.
Přehled poskytovatelů služeb v Jet
Pro názornost jsme si ukázali logování jakožto naprosto jednoduchou službu. Ovšem v Jet je samozřejmě daleko více služeb a jejich poskytovatelů. Zde je jejich seznam.
A vám pochopitelně vůbec nic nebrání vytvářet si vlastní služby s využitím obdobného mechanismu a filozofie. A nepotřebujete k tomu žádný komplexní framework ;-)
| Služba / subsystém | Garant služby | Metoda pro vložení poskytovatele | |
|---|---|---|---|
| Autentizace a autorizace | Jet\Auth | Jet\Auth::setController( Jet\Auth_Controller_Interface $controller ) |
Poskytovatelem služby je tak zvaný Auth Controller implementující Jet\Auth_Controller_Interface. Úkolem tohoto kontroleru je řídit logiku práce s uživateli, přesněji logiku autentizace a autorizace. Neexistuje žádný výchozí Auth Controller. Stejně tak součástí frameworku není žádná implementace Auth Controller. Tyto kontrolery jsou vždy součástí aplikačního prostoru - aplikace. Je tedy plně na vývojáři jak logiku implementuje a nic nebrání jakýmkoliv úpravám. Součástí ukázkové aplikace jsou tři kontrolery. Při použití Jet MVC se instance kontroleru vkládá do garanta služby v rámci inicializátoru báze. |
| Autoloader | Jet\Autoloader | Jet\Autoloader::register( Jet\Autoloader_Loader $loader ): void |
Systém pro automatické nahrávání tříd je ve skutečnosti tvořen jednotlivými moduly, které je do něj nutné vložit při inicializaci aplikace. Těchto modulů samozřejmě může být (a v praxi je) víc. Ve výchozí konfiguraci inicializaci naleznete ve skriptu ~/application/Init/Autoloader.php |
| Keš autoloaderu | Jet\Autoloader_Cache | Jet\Autoloader_Cache::init( Jet\Autoloader_Cache_Backend $backend ) |
Backend keše systému automatického nahrávání tříd je nutné vložit.
Ve výchozí konfiguraci inicializaci naleznete ve skriptu ~/application/Init/Cache/Autoloader.php |
| Správce aplikačních modulů | Jet\Application_Modules | Jet\Application_Modules::setHandler( Jet\Application_Modules_Handler $handler ) : void |
Správce aplikačních modulů není nutné vkládat. Systém má výchozí implementace, která se použije pokud při inicializaci nebyl vložen jiný správce. Tedy je možné vložit alternativního správce modulů, ale v tomto případě není nutné vkládání provádět. Správa aplikačních modulů používá i systém továren. |
| Logger | Jet\Logger | Jet\Logger::setLogger( Jet\Logger_Interface $logger ): void |
Systém zabezpečující obecné logování. Implementace loggeru je vždy součástí aplikace a ne frameworku. Ukázková aplikace obsahuje předpřipravené logery. Při použití Jet MVC se instance loggeru vkládá do garanta služby v rámci inicializátoru báze. |
| Posílání e-mailů | Jet\Mailing | Jet\Mailing::setBackend( Mailing_Backend_Abstract $backend ): void |
Systém posílání e-mailů potřebuje backend, který zajistí samotné odeslání e-mailu. Výchozí backend zajistí odeslání před standardní prostředky samotného PHP a tento výchozí backend není nutné vkládat. Výchozí backend je použit automaticky pokud jiný backend není vložen do garanta služby. I zde platí, že je možné vložit vlastní backend, ale pokud vám stačí backend výchozí, pak vkládání není nutné provádět. |
| Hlavní router MVC | Jet\MVC | Jet\MVC::setRouter( MVC_Router_Interface $router ): void |
Taktéž hlavní router Jet MVC není nutné vkládat, ale má svou výchozí implementaci, ale zároveň je možné vytvořit si vlastní implementaci routeru a tu vložit. Zajímavostí je, že router Jet MVC využívá i systém továren. |
| Keš MVC | Jet\MVC_Cache | Jet\MVC_Cache::init( MVC_Cache_Backend $backend ): void |
Keš Jet MVC je nutné inicializovat a vložit backend do kontejneru / poskytovatele služeb na místě k tomu určeném. Tedy ve skriptu: ~/application/Init/Cache/MVC.php K dispozici jsou dva připravené backendy využívající pro ukládání buď soubory, nebo Redis. A samozřejmě nic nebrání implementovat libovolný další backend a ten vložit do systému. |
| REST API server | Jet\RESTServer | Jet\RESTServer::setBackend( RESTServer_Backend $backend ) : void |
Backend REST API serveru má na starosti konkrétní implementaci čtený HTTP požadavků naopak tvorbu konkrétních HTTP odpovědí. Pokud tedy chcete změnit výchozí chování REST API serveru, tak to samozřejmě není problém. I zde platí, že existuje výchozí implementace, která se inicializuje automaticky a ve výchozí situaci tedy není nutné backend vkládat. |
| Překladač - ukládání slovníků | Jet\Translator | Jet\Translator::setBackend( Translator_Backend $backend ) : void |
Úkolem backendu překladače je načítat a ukládat slovníky překladů. I v tomto případě existuje výchozí implementace, která operuje se soubory a tento výchozí backend je použit automaticky pokud není vložen jiný. |