Jak injectovat statickou laděnku?
- maarlin
- Člen | 207
Občas mám kus kódu, kde potřebuji natrvalo (tj. ne jen pro dočasný debugging) využít laděnky.
Typický příklad je JSON API, kde odchytávám obecnou Exception, která by jinak vylítla až do ErrorPresenteru a vykreslila tak HTML error na JSON API, což je z principu nežádoucí.
Když tímto způsobem zakrývám ErrorPresenter, nechci zahazovat všechny exceptions, které tam nastanou, chci je dál logovat.
try {
// do something useful
} catch( \Exception $e ) {
Debugger::log( $e );
$this->draw_500_json_response();
}
Protože kód chci mít patřičně otestovaný a být schopen cokoliv předat jako mock, důkladně využívám DI.
Laděnku ovšem skrz DI jde předat dost blbě a ještě hůř namockovat její statické metody.
Ano, mohl bych si vyrobit něco jako ErrorJsonPresenter a nechat to probublat až tam, ale často prostě chci danou exception ošetřit lokálně (co když třeba v tom API chci zpátky v response přdat nějaké parametry navíc a nechci aby to bublalo k nějaké obecné JSON 500?).
Z praktického (= lenivého) hlediska bych teoreticky chápal, proč jsou všechny metody statické, ale z výše uvedeného důvodu mi dává větší smysl je statické nemít.
Máte někdo na tento problém řešení / nějaký lepší důvod, proč laděnka žije stále se statickými metodami?
Editoval maarlin (26. 8. 2012 22:19)
- Filip Procházka
- Moderator | 4668
Udělej si třídu logger, kterou zaregistruješ do DIC a která bude tajně pracovat s laděnkou :)
- Filip Procházka
- Moderator | 4668
Protože není důvod aby nebyla statická? Laděnku není důvod mockovat, ani vytvářet několik instancí, protože nemáš šanci vytvořit několik oddělených prostředí, kde by se každé chovalo jinak.
- Filip Procházka
- Moderator | 4668
Bluescreen, Bar a Logger by skutečně služby být mohly, to zní rozumně. Ale nesouhlasím s tím, že se špatně konfigurují.
- Panda
- Člen | 569
Já osobně nevidím moc důvod, proč by laděnka měla být objektová.
Tím, jak moc ovlivňuje vykonávání skriptu na globální úrovni, mi vůbec
do konceptu DI a služeb nepasuje. Něco, co při své inicializaci nastavuje
error_reporting
, přidává globální konstanty kvůli
kompatibilitě, volá register_shutdown_function
,
set_exception_handler
, set_error_handler
a další
věci, by podle mě opravdu nemělo být jako objektová služba – operuje
globálně a rozhodně nepůjde izolovat do objektu. Navíc je nutné laděnku
inicializovat ještě před tím, než se skript o nějakých službách
dozví, čímž se opět z konceptu služeb vymaňuje.
Osobně bych volil řešení, které je zmíněno hned ze začátku: laděnku ponechat statickou a připravit nějaké rozumné mockovatelné rozhraní a adaptér, který bude některé funkce laděnky zpřístupňovat.
Editoval Panda (27. 8. 2012 15:29)