Patrik Votoček

weBlog



Service vrstva Doctrine (2/2)


předchozím článku jsem řešil, zda o data žádat přímo repository, či zda žádat service. V tomto článku bych rád otevřel diskusi nad dalším „problémem“, který řeším.

Dalším problémem je totiž „spárování“ service s entitou. V doctrine si totiž entita sama říká, jaká repository se o ní má starat (čistotu tohoto řešení nechejme stranou). Je to jednoduché, zvyknete si na to a kupodivu je to i celkem praktické řešení. Jak tedy řešit svázání service s entitou. A jak toto svázání napasovat na Nette Framework?

Anotace + DoctrineContainer

Jednou z možností je využití anotace, stejně jako je tomu u repository. Zavedeme si tedy anotaci service. Ukázka kódu:

/**
 * @entity
 * @service(class="App\Model\FooService")
 */
class FooEntity extends \Nella\Doctrine\Entity
{
        // ...
}

$service = $this->context->doctrineContainer->getService('App\Model\FooEntity');

Shrnutí

  • + mám vše na jednom místě
  • – entita „ví“ , jaká služba jí zpracovává

Globální DI kontejner

Druhou možností je modelové služby registrovat, jako klasické služby do jednoho velkého „globálního“ kontejneru. Opět ukázka

common:
        services:
                fooModelService: {class: 'App\Model\FooService'}

To byla registrace služby do kontejneru, teď se podívejme na použití.

$service = $this->context->fooModelService;

Shrnutí

  • + entita nemá žádnou vazbu na službu
  • – nutnost „složité“ registrace služby do kontejneru

Které z těchto řešení zvolit a proč?

Pokud se ptáte proč jsem nepsal třetí možnost – a to využití doctrine kontejneru bez anotací (s registrací). Tak je to proto. že jsem nenašel smysl / důvod, proč by měl existovat další kontejner, když není ničím speciální.

4 komentáře


HosipLan

nový

Doporučoval bych ti přečíst si http://goo.gl/KJdb2 a http://goo.gl/cKzQk.

Zastávám názor, že ani jedno řešení není správné™, protože se snažíš mapovat entitu na službu 1:1, což nemusí vždy platit. To by ale nebyl problém.

Nevidím důvod, proč by mělo být někde napsané, že tato entita patří pod tuto službu, nebo naopak.

Nebylo by daleko jednodušší prostě to nedefinovat? Jen si zaregistruji službu a entitě i DI Containeru bude jedno, co s čím pracuje. Službě předám EM a ta už se postará a zařídí si co potřebuje? Nebo ještě lépe, definovat její působnost tím, že jí předám jeden nebo více repozitářů?

HosipLan avatar

Jan Tichý

nový

Pokud v aplikaci i tak používáš DI kontejner, jakože asi jo, a budeme se teď bavit o dekomponovaném a znovupoužitelném návrhu, tak druhá možnost.

V té první vnášíš do kódu zbytečnou komplexitu a závislosti, které vůbec nepotřebuješ a jenom Ti budou komplikovat život. Omezuješ si tím konfigurovatelnost, použití více různých servis v různých situacích (aplikace, testy, jiná aplikace, jiné testy…) pro jednu entitu apod.

To, že je „vše na jednom místě“ je špatně, pokud tohle jedno místo používáš na více různých místech a v každém z těch míst to tam potřebuješ mít jinak.

Naopak napsat jeden řádek do konfigurace kontejneru mi přijde daleko méně práce, než psát anotace do entit, a navíc mi to takhle s odstupem přijde mnohem přehlednější.

A samozřejmě pokud máš celou aplikaci postavenou na DI, tak ta „ukázka použití“ u druhého příkladu je taky nadbytečná, protože tam nikde nic takového nemusíš psát…

Jan Tichý avatar

NoxArt

nový

Souhlas s Hosiplanem, mapování Entita – Service nemusí být 1:1 … to se stává očividnější čím méně je Service jen obálka nad repository

V D2 si entita říká jaké repository se defaultně použije…no asi to není úplně ok, ale…na druhé straně nemusí se to vůbec používat a použít vlastní repository není vůbec problém, jen se bude lišit jeho získání což se vyřeší v kontejneru

NoxArt avatar

juzna.cz

nový

Myslim ze v cistem reseni by entita nemela vedet ani o repozitory, protoze tech muze byt taky vic. Spis bys mel definovat kazdou repozitory jako zvlastni tridu a repozitory by vedela, jake entity v ni jsou. A sluzba by zase vedela, ze kterymi repozitory ma pracovat.

Takhle to mame v praci postavene nad Zend Db a to se mi zda jako spravnejsi reseni. Je to ale vic psani. A hlavne v Doctrine kolikrat ani specialni repozitory class nepotrebujes a vystacis si s tou obycejnou zabudovanou.

juzna.cz avatar

Přidej komentář



cenzuruje váš poskytovatel připojení?

Kategorie

Čtu

Kamarádi