K čemu se má používat decorator?

CZechBoY
Člen | 3608
+
0
-

Zdravím,
nedávno jsem se dočetl o síle decoratoru a zajímalo by mě k čemu ho používáte.
Napadlo mě ho použít k nastavování závislostí pro Base* třídy aniž bych musel povolovat inject.
Důvod proč nechci použít inject je jednoduchý: musel bych pod každou třídu psát injet:yes a někdy (klasika) na to mohu i zapomenout.
Je to správná volba? Jak nastavujete závislosti v nižších úrovních dědění?

Díky za názory.

Editoval CZechBoY (10. 5. 2016 12:21)

David Matějka
Moderator | 6445
+
+2
-

Ano, je to urceny pro Base tridy. Ja to pouzivam prevazne (nebo spise vyhradne) u BaseControl

Jan Tvrdík
Nette guru | 2595
+
+1
-

CZechBoY napsal(a): musel bych pod každou třídu psát injet:yes a někdy (klasika) na to mohu i zapomenout.

Přes decorator můžeš povolit inject pro všechny potomky konkrétní třídy.

David Matějka
Moderator | 6445
+
0
-

Jo a souvisejici diskuze https://forum.nette.org/…omci-zabyvat, na zaklade ktere to vzniklo

CZechBoY
Člen | 3608
+
0
-

@JanTvrdík aha, no stejně se mi injectování moc nelíbí – public property, kterou někdo někde špatně použije je prostě zlo. Vim že existuje nějaká kdyby alternativa, která umožní i přes nižší viditelnost injekci, ale to už je moc magie…

@DavidMatějka tak to je supr. Myslíš že je ok mít třeba traitu TCached, která vše zařídí aby mi jela cache, a pak třeba v nějakým modelu použiju use TCached? Nebo to je už moc?

Díky za odpovědi

David Matějka
Moderator | 6445
+
0
-

@CZechBoY traity podporovany nejsou

CZechBoY
Člen | 3608
+
0
-

Ajaj, to je schválně nebo je nějaký problém s implementací?

David Matějka
Moderator | 6445
+
0
-

s implementaci problem neni, ale viz ta diskuze:

S traity nevím, jednak by to chtělo řešit možné aliasy metod, ale hlavně si nejsem jistý, jestli to nepodporuje prasení…

(osobne by se mi to taky libilo)

CZechBoY
Člen | 3608
+
0
-

Pokud zapnu inject na všech Base* třídách tak se stejně aplikujou i na property/metody v traitě, ne?

Editoval CZechBoY (10. 5. 2016 13:49)

David Matějka
Moderator | 6445
+
0
-

ano

CZechBoY
Člen | 3608
+
0
-

Tak inject by mi stačil, pokud by se daly vypnout ty public property :-/
Asi forknu nette/di a přidám podporu trait… Nebo to tvoje librette/setup umí traity?

edit: librette/setup umí traity, ale je použitelný pro nette 2.3?

Editoval CZechBoY (10. 5. 2016 14:11)

David Matějka
Moderator | 6445
+
+1
-

CZechBoY napsal(a):

edit: librette/setup umí traity, ale je použitelný pro nette 2.3?

koukam, ze ho furt pouzivam (prave kvuli traitam) a projekt jede na 2.3, takze jo :)

CZechBoY
Člen | 3608
+
0
-

@DavidMatějka Můžeš otagovat nějakou stable verzi? dík ;-)

pata.kusik111
Člen | 78
+
0
-

Možná s křížkem po funuse, ale přidám ještě jednu konkrétní aplikaci.

Potřebovali jsme logovat chyby v Nette aplikaci do NewRelic. Nebylo nic jednoduššího, než vytvořit

<?php
use \Tracy\ILogger;
/**
 * Class LoggerDecorator
 */
class LoggerDecorator implements ILogger
{
	/** @var ILogger */
	private $oldLogger;

	public function __construct(ILogger $oldLogger)
	{
		$this->oldLogger = $oldLogger;
	}
	/**
	 * @param string|array|Exception
	 * @param string
	 * @return string logged error filename
	 */
	function log($value, $priority = self::INFO)
	{
		$exceptionFile = $this->oldLogger->log($value, $priority);

		if (is_array($value)) $value = implode(' ', $value);

		if($value instanceof \Exception) {
			newrelic_notice_error($value->getMessage(), $value);
			return $exceptionFile;
		}

		newrelic_notice_error($value);
		return $exceptionFile;
	}
}

a pak v boostrapu zavolat:

$oldLogger = \Tracy\Debugger::getLogger();
$newLogger = LoggerDecorator($oldLogger);
\Tracy\Debugger::setLogger($newLogger);

Kód úmyslně zjednodušen pro ukázku. Jinak celé rozšíření je na githubu

CZechBoY
Člen | 3608
+
0
-

@pata.kusik111 Moc nechápu jak to souvisí s decoratorem, ale budiž :D

David Matějka
Moderator | 6445
+
+1
-

@pata.kusik111 @CZechBoY decorator pattern != nette decorator extension :)

pata.kusik111
Člen | 78
+
0
-

Asi v tom případě zas nechápu ten decorator pattern já. Přidávám pomocí dekoratoru interní funkcionalitu pro Tracy Logger (v tomto případě ještě logování do New Relicu), a to bez toho, abych změnil vnější API objektu (implementování interface ILogger). Podle mě tohle je naprostá definice decorator pattern. Ale prosím, opravte mě, poučte mě, rád bych to pochopil správně, pokud to chápu špatně.

David Matějka
Moderator | 6445
+
+2
-

@pata.kusik111 decorator chapes dobre. ale decorator extension z nette dela neco jineho a s decorator patternem nesouvisi.

CZechBoY
Člen | 3608
+
0
-

@DavidMatějka otaguješ pls tu stable verzi? :-)
@pata.kusik111 nicméně ten tvůj kod se mi hodí na https://forum.nette.org/…astni-logger

pata.kusik111
Člen | 78
+
0
-

@DavidMatějka oh, aha, tak to se omlouvám, nějak jsem vůbec nepochopil, o čem celá tato diskuze je.

Tomáš Votruba
Moderator | 1114
+
0
-

Pokud tu stále hledáš opověď, mrkni na vlákno Jak funguje Decorator Extension a kdy ho použít?