Změny generovaných továrniček v Nette DI 4.0
- David Grudl
- Nette Core | 8227
V Nette 4.0 bych rád vymetl historické relikty a vylepšil věci, které vznikly postupným vývojem a dnes již nejsou aktuální nebo by se daly udělat lépe. Důležitá je vaše zpětná vazba, protože můžete věci používat způsobem, který nepředpokládám.
Postupným vývojem prošly i generované továrničky.
Verze 4.0 bude vyžadovat, aby metody get()
nebo
create()
měly uvedený návratový typ (nativně, nikoliv
anotací). To předpokládám už všichni stejně dávno používáte.
Rád bych vylepšil i syntax generovaných továrniček. Současná podoba:
services:
fooFactory:
implement: FooFactory
create: Foo(%bar%, %lorem%)
parameters: [string ipsum, ?Bar bar, ?int lorem: null]
setup:
- setIpsum(%ipsum%)
Co tady vidím jako problematické?
- název klíče
factory
, který prostě není úplně šťastně zvolený s ohledem na zavádějící význam v případě továrniček. Do verze DI 2.3 existoval klíčcreate
, ale ten se neujal. Uvažuju nad pokusem o znovuvzkříšení jakožto aliasu, trojice slovesimplement
,create
asetup
mi připadá srozumitelnější. - klíč
parameters
: z mého pohledu jde o historický relikt z doby, kdy ještě neexistovalo automatické předávání parametrů do konstruktoru, a který v dnešní době není potřeba. Pokud ano a používáte jej, napište prosím jak a proč. %parametry%
ve create: použití stejné syntaxe pro parametry tovární metody definované v klíčiparameters
a pro globální parametry má na jedné straně svou logiku, na druhou stranu to může být matoucí. Myslím, že stejně jako v předchozím bodě jde o historický relikt, který nahradilo automatické předávání parametrů do konstruktoru. Ale možná se pletu, tak dejte opět vědět.%parametry%
v setup: opět řeším stejnou syntaxi pro parametry tovární metody a globální parametry. Tady už se netýká konstruktoru, takže k automatickému předávání parametrů nedochází. Připadalo by mi lepší parametry zapisovat jakosetIpsum($ipsum)
a vyhnout se procentové syntaxi. A zároveň by nebylo potřeba vytvářet klíčparameters
, jako nyní.
Výsledek by tedy mohl vypadat takto:
services:
fooFactory:
implement: FooFactory
create: Foo # případně Foo($bar, $lorem)
setup:
- setIpsum($ipsum)
Pokud v konfiguraci není klíč setup, lze používat i zkrácenou podobu:
services:
fooFactory: FooFactory(Foo)
Tento zápis mi nepřipadal úplně srozumitelný, ale nenapadá mě, jak by šel vylepšit, takže je to asi věcí volby každého, zda zkratku použije nebo ne.
- David Grudl
- Nette Core | 8227
Doplňuji:
class Foo
{
public function __construct(Bar $bar, int $lorem = null)
{
}
public function setIpsum(string $ipsum)
{
}
}
interface FooFactory
{
function create(string $ipsum, ?Bar $bar, int $lorem = null): Foo;
}
- Polki
- Člen | 553
- souhlas – klíč
factory
ve mě evokuje, že se jedná o třídu továrny, ne o třídu, kterou má generovaná továrna tvořit.create
mi přijde vhodnější. - souhlas – Až do teď jsem nevěděl, že to existuje. První co mě napadlo, tak že by tím šly přepsat výchozí hodnoty daných parametrů, případně dynamicky přidávat další. Nenapadá mě ale případ, kde bych to využil
- souhlas – Parametry dodá buď přímo DI, nebo se automaticky předají
z create metody továrny. Takže mi přijde zbytečné mít možnost si to
definovat ještě zde, co se kam předává. Nikdy jsem nepoužil. Na předání
globálního parametru používám
arguments: [parameterFromConfig: %myParameter%]
, takže za mě není třeba umožňovat definovat předání parametru explicitně zde. - souhlas – pro mě jsou sice parametry, které předávám do metody
create
povinné a tedy je cpu do konstruktoru. Setup používám jen když chci nastavit nepovinné parametry, které definuji v configu, takže já mám jasno, že v setup jsou vždy jen globální parametry. Rozumím tomu ale, že někdo má konstruktor co nejjednodušší a tedy spoustu parametrů si nastavuje nepovinně i když je vyžaduje metoda create a pro takové případy by se hodilo rozlišit, jestli se má předat globální parametr, nebo parametr funkce create.
Pokud jde o:
services:
fooFactory: FooFactory(Foo)
co takto:
services:
fooFactory: FooFactory(): Foo
Případně místo dvojtečky jiná konstrukce místo dvojtečky, která by připomínala návratovou hodnotu a nekolidovala s ostatními dvojtečkami?
- jiri.pudil
- Nette Blogger | 1032
Asi moc nepřispěju do diskuse, protože jsem žádné takové divoké nastavování u továrniček nikdy nepotřeboval. I proto bych byl moc rád, aby zůstal zachován i ten úplně nejzkrácenější zápis:
services:
- FooFactory
DI compiler si s tímhle vystačí a definici služby – na základě
detekce rozhraní a reflexe create()
metody – vygeneruje úplně
správně dle očekávání. Nevidím potřebu duplikovat
FooFactory(Foo)
v configu, když už mám v kódu
create(): Foo
.
- Pavel Kravčík
- Člen | 1195
Vypadá to super!
Možná je poznámka – na první dobrou není jasný rozdíl mezi následujícím:
- {implement: FooFactory, arguments: [%peter%]}
- {implement: FooFactory, parameters: [%john%]}