Entity, Repository, Facade rubrika: Programování: PHP

3 vaclav
položil/-a 18.11.2016
 
upravil/-a 18.11.2016

Ahoj,

stále více a více v diskuzích (kolem Doctrine) vidím informace k ORM - entity, repository, services a fasády. Myslím, že v tom nemám stále jasno. Máte někdo ucelený názor či zdroj co a kam psát. Co a jak oddělit?

Komentáře

  • Anonym : Slyšel jste někdy o Domain-Driven Design? Možná by vám to pomohlo v chápání těchto věcí více než se to snažit pochopit skrze ORM. Většinou to vede k přemýšlení v plochých objektech, k předčasným závěrům a nepochopení rozdílu mezi doménovým a perzistentím modelem -- vlastní zkušenost. 18.11.2016
odkaz
2 cydreb
odpověděl/-a 2.1.2017
 
upravil/-a 2.1.2017

V 3 vrstvovej architektúre webových aplikácii platí:

Dátová vrstva

  • obsahuje entity a repository
  • repository prislúcha k entity, avšak nie každá entity musí mať repository
  • repository obsahuje len dotazy na databázu, neobsahuje žiadnu biznis logiku

Biznis vrstva

  • obsahuje service
  • service volá repository, alebo ďalšie service
  • service obsahuje biznis logiku
  • service slúži ako facade (pretože volá viaceré repository)
  • biznis vrstva je závislá len na dátovej vrstve

Prezentačná vrstva

  • patrí sem REST / SOAP / Controller, ktoré volajú service, nevolajú repository
  • neobsahuje biznis logiku
  • prezentačná vrstva je závislá len na biznis vrstve

V niektorých prípadoch sa biznis vrstva vynecháva a vtedy sa presúva biznis logika do repository, resp. do prezentačnej vrstvy. Takýto prístup neodporúčam, pretože takú aplikáciu je obtiažnejšie pokryť testami, metódy sú príliš zložité, nie sú oddelené zodpovednosti atď ...

Nie sú to veci, ktoré by boli špecifické pre Doctrine, resp. Symfony, ale jedná sa o všeobecné koncepty a návrhové vzory, ktoré je možné použiť aj inde.

Komentáře

  • maryo : Co si představit pod pojmem service? Jestli je to např. třída ArticleService apod., tak to je dost procedurální přístup. Ne že by to nutně muselo být špatný dělat něco procedurálně, to zas ne, jen mi přijde, že si tohle lidi spojujou s OOP, což neni správně. Použijí ORM, aby mohli mapovat objekty do databáze a potom skoro všechnu business logiku nasází do tříd typu XxxService, na tomhle řešení je něco trochu nemocnýho :P. Ale možná si pojem service špatně vykládám, narážim na to často. 2.1.2017
  • Kit : @maryo: Když vidím třídu XxxService, tak se osypávám. Ano, je to procedurální přístup v OOP - stejně jako použití repository, kde se pod honosným názvem v lepším případě skrývá obyčejná stromová datová struktura. OOP je naopak záležitostí stmelení algoritmů a datových struktur do funkčních celků a jejich vzájemné komunikace. 2.1.2017
  • maryo : Jj, taky se osýpám no :D. Ale zase na Repository nic špatnýho nevidim. 2.1.2017
  • Kit : @maryo: Repository je jen datová struktura s "objektovým kabátkem". I takové struktury potřebujeme. Často k tomu účelu vyhoví array() nebo stdClass() a není nutné stavět komplikované třídy. 2.1.2017
  • Taco : @cydreb: Je pěkné, že jsi prostě popsal jednu z několika možných architektur. Ono to asi víc nemá smysl rozebírat. I tak se i takhle jedna jednoduchá architektura dá nalézt v mnohých více či méně odlišných variantách. Já třeba častěji místo Datové vrstvy používám Persistentní, a entity mám jako součást Business vrstvy. 2.1.2017
  • cydreb : @maryo Pod service sa dá predstaviť napr. AnalyticsService, ktorý bude pripravovať podklady pre analýzy a ktorý bude využívať ArticleRepository, CommentRepository, UserRepository. Máte na mysli niečo konkrétne, čo Vám príde "nemocné" na tomto riešení? 3.1.2017
  • cydreb : @Taco Celkom nerozumiem tomu, čo píšete. Entita je perzistentná trieda. Ak máte perzistentnú vrstvu, tak ako môžu byť perzistentné triedy súčasťou biznis vrstvy? 3.1.2017
  • Kit : @cydreb: Tyto service by měly být součástí tříd Analytic, Article, Comment a User. Není důvod, proč by měly být separovány někde jinde. 3.1.2017
  • harrison314 : @Kit: napriklad kvoli SRP. 3.1.2017
  • Anonym : @cydreb Entitou myslí @Taco objekty s identitou, jak tomu říká Evans a spol.; ty nemají žádnou znalost ukládání do databáze či jinam. Takže je to jen stejný název pro jiné věci. 3.1.2017
  • Kit : @harrison314: Právě SRP ty třídy Service porušují. Proto by měly být služby společně s daty. 3.1.2017
  • Anonym : @Kit Service je třída, která pracuje s Entitama klidně přes různé kontexty, pak tedy data pro service jsou tyto entity a metody nad nimi operují. Když je možné funcionalitu implementovat v entitě, pak není service potřeba, pokud ale ne nebo dokonce musí sahat do DB, pak v entitě být nemůže, protože tam perzistence nemá co dělat. Service je normální objekt, který má větší rozhled po aplikaci. Ale pokud sem dáš odstrašující příklad anemického modelu, pak je jasné, že service z toho vyjde špatně. 3.1.2017
  • harrison314 : AK sluzby beries ako fasady nad domenovymi objetami tak nie. Je viac pristupov. Pozri si prednasku co sem dal radimkunz o navrhovych vzoroch. Mne osobne vadi ak mam v jednej triede aj perzistnu vrstvu, aj bussines logiku aj prezentacnu vrstvu. 3.1.2017
  • Taco : @uetoyo: Doplním, že nejenom persistence, ale jakékákoliv další logika která jde napříč entitama, kontextem nebo časem. Samozřejmě, že by to šlo otočit, a tu službu vstřikovat do entity, aby to jakože dělala ona, tak jak to tu již @Kit ukazoval, ale domnívám se, že není žádný racionální důvod to tak dělat. 3.1.2017
  • Taco : @cydreb: Jak psal @uetoyo. Já entitám pak říkám "doménové objekty". Ale naivně jsem si myslel, že když si vypůjčím názvosloví, že to usnadní pochopení. No, evidentně ne :-) 3.1.2017
  • Anonym : @harrison314 Komu patří ten poslední komentář? Jinak na přednášku se podívám, v architektuře se mám co učit. 3.1.2017
  • harrison314 : @uetoyo: Kitovi. 3.1.2017
  • maryo : Ne všechny doménový objekty jsou entity. Pokud existuje objekt, kterej potřebuje sahat do DB, nemusí se to ihned dělat nebo pojmenovávat "service", je to takovej příliš obecnej pojem. Pokud to obsahuje business logiku, nepřijde mi ani, že by to odpovídalo tomu, co popisuje Fowler jako Service Layer, http://martinfowler.com/eaaCatalog/serviceLayer.html Jindy se tak řiká objektům zaregistrovanejm v DI containeru. Často mi to přijde minimálně jako rezignace na pojmenování. Přijde další programátor, bude mít za úkol přidat další funkcionalitu šahající do DB pracující s tou entitou, uvidí takhle pojmenovanou třídu a dost možná to tam šoupne, páč uvídí třídu, která "dělá něco s entitou třídy X", ale už neřiká co, takže přidá další důvod ke změně (čímž poruší zmiňovaný SRP). 3.1.2017
  • Anonym : @maryo "Ne všechny doménový objekty jsou entity." Samozřejmě ... např. Value objects. Pojmenovávat to jako service nemusíte. DDD je o tom umět ty objekty správně zařadit. Service je service i když se nejmenuje service. Podívejte se na Redux respektive Flux architekturu -- jen se to přejmenuje a pozmění terminologie, už to není event sourcing a půlka lidí je zmatená. 3.1.2017
  • Taco : @maryo: Tak abych persisteoval objekt, tak si k tomu vytvořím jednu skupinu nástrojů (v názvosloví se stejně musím přizpůsobit legaci kódu). Pokud chci vytvořit nad jedním nebo více objekty nějaký proces, tak to bude zase jiná skupina nástrojů. Když o tom budu mluvit s kolegama, tak tomu budu říkat služba. Když budu volit jména tříd, tak budu asi kreativnější :-) 3.1.2017
  • maryo : @uetoyo: Jojo, já vim, proto to píšu kdyby mezi tím někdo dělal rovnítko :-). Flux i event-sourcing trochu znám, domain-driven se znažím jet i když asi ne úplně striktně, páč v tom mám pořád mezery, nerozumim tomu zas super dobře abych to považoval za čistý DDD (ono kdo jo a jedeme v dost malym teamu). A ono co se kódu týče je DDD víceméně jen OOP + ubiqutous language a zbytek (což je dost velká část) neni vůbec o kódu, ale o procesech a komunikaci viz např. event storming i když tu Evansovu knihu jsem nečetl. Já "místo" servis používám Commandy/Handlery (viz třeba http://php-and-symfony.matthiasnoback.nl/2015/01/a-wave-of-command-buses/ kdo by náhodou neznal). Taky domain eventy (to už neni "místo" servis) i když jsem je možná trochu "ohnul" aby byly součástí transakcí a mohl jsem v listenerech šahat do databáze v tom konkrétním stavu před commitem (a nemusel tak dělat "ručně" to, co umí databáze líp a efektnějc). A teprve to, co mi přijde, že se "tam nehodí/nevejde" hodně laicky řečeno, tak pro to vytvořim nějakej objekt, kterej ale taky nepovažuju za servisu. @Taco: Tak jedna věc je jak by to člověk chtěl, druhá věc je být konzistentní, to má často přednost, zvlášt pokud jde o práci na legacy projektech kde je už architektura daná. Na těch moc nedělám (krom toho legacy co jsem zanesl já :-], nedělám si iluze že by to někdo za legacy nepovažoval). Já jsem se hlavně snažil upozornit, že dělit to takhle striktně na 3 části mi nepřijde dobře, že ne každej si pod service vrstvou představí to, co by service vrstva měla obsahovat a že mi ten pojem přijde trochu zprofanovenej anemic modelem. Proto jsem psal, že si nejsem jistej co si pod tim pojmem představit a z toho popisu v tý odpovědi to neznělo správně. Netvrdím, že to každej dělá špatně, to ne. "Eric Evans's excellent book Domain Driven Design has the following to say about these layers. Application Layer [his name for Service Layer]" To mi asi přijde i výstižnější název. "This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down." 3.1.2017
  • harrison314 : @maryo: Servisna vrstva != service triedy. Servisna vsrtva su triedy a API, ktore ti zabezpecuju infrastrukturu, spravu zdrojov (connection pool, framework pre webove sluzby, cache). S servisnej vrstve nie je ziadna bussines logika. Viem, ze je v tom trochu zmetok, ale takto to mam v knihe o aplikacnych architekturach od mudrejsich ludi. 4.1.2017
  • maryo : Jj, to je celkem konzistentní s tou anglickou citací - Fowler. Snažil jsem se, možná trochu zmatečně, naznačit (aniž bych znal přesnou definici, protože na spoustě místech tvrděj něco jinýho), že hodně programátorů to špatně chápe a že v tý odpovědi od @cydreb mi přijde, že to správně neni :). 4.1.2017

Pro zobrazení všech 2 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.