Proč zrovna tolik vrstev abstrakce? Každá vrstva přináší kód navíc, který nic nedělá, ale musí se udržovat. Rozhraní, se kterým se musí ostatní programátoři seznámit. Práce s vaší vlastní vrstvou pro ně bude komplikovanější než práce přímo s rozšířenou a dobře zdokumentovanou knihovnou, kterou znají z jiných projektů. Kvůli každé maličkosti musí přidávat funkcionalitu do každé z vrstev.
Pokud nad Vaší otázkou budu přemýšlet z hlediska mého projektu, který je použit na microservices, tak mi tolik vrstev abstrakce dávají smysl. Každá "servisa" má tuto architekturu. Každá může použít vhodnější typ databáze a přitom si zachovat velmi podobný tvar jako jiná "servisa". Programátor se zorientuje dobře v každé z nich a dokumentaci knihovny bude řešit až pokud se bude potázet s konkrétní technologií.
Pokud vytvoříme klubko špaget s použitím různých technologií a kód nebude mít řád podpořený přehlednou abstrakcí(architekturou), tak i když jsou technologie dobře zdokumentovány, tak si myslím, že se časově dobereme k horšímu výsledku.
Nehledě na to, že pokud se pokusíme na takový kód napsat unit test, tak spíše selžeme.
> mého projektu
problémy, o kterých jsem psal, vyniknou hlavně při práci na cizích projektech. Moderní frameworky od psaní vlastní tzv. domain vrstvy většinou odrazují. Cílem je omezit množství kódu specifického pro vaši aplikaci na minimum. Architekturu dodává framework.
24. 1. 2020, 10:59 editováno autorem komentáře
@gilll
No dokonce, viděl jsem přednášku nějakého maníka z teamu Doctrine ORM a ten tam říkal, že vývoj aplikace by měl být postavený jenom na entitách bez jakéhokoliv úložného enginu, ale tak beru to trochu trošku více méně jako "drsnou hlášku do přednášky" než nejlepší každodenní praxi. To už je až příliš šílená abstrakce a ani není nutná bych řekl, často se ví dopředu kde ty data budou ...
24. 1. 2020, 23:53 editováno autorem komentáře
@uetoyo
"Zajímavé. Docela bych tuhle metodu vývoje chtěl vidět, nikoliv však zažít."
Tak pokud jste někdy pracoval s Entitami (jak je používá např. Doctrine ORM) tak prostě pracujete na základě znalostí deklarovaných metod a návratových typů, nakonec si něco namockujete do testů nebo použijete pro testy datové fixtury které použijete pro mockování. Na tom nic není. Ale není to řekl bych úplně nutné vzhledem k tomu že je to méně konfortní oproti vývoji kdy stejně víte jestli svá data stavíte na MySQL nebo Postgre či co, protože i přes teoretické žádané vlastnosti ORM, ona ta ORM nakonec stejně nějaké queries poskládat musí, že ... a ony ty automaticky skládané dotazy mohou velice rychle začít dělat výkonostní problémy. A dělají. Pak se dají sice použít nějaké Native Query, pak už se ale nebavíme z 1/2 o ORM i když to pořád ještě nějaké výhody přináší
25. 1. 2020, 18:18 editováno autorem komentáře
@gilll
Neřekl bych protože striktní oddělení domain vrstvy od ORM stále dává možnost logicky i prakticky oddělit vrstvy aplikace od sebe - je to fakt výhodné např. při testování jednotlivých vrstev - jednou jsem dokonce zažil že se zvažoval přechod z jednoho zdroje dat (i engine) na jiný a díky neoddělení vrstev se to stalo prakticky nemožné a tak se přišlo s tím že se zdroje zkombinují a víte jak? Tak že se vrstvy začaly striktně oddělovat, protože každý už si byl vědom budoucích problémů. Uznávám ale že budování takové aplikace je místy až overhead a bobtná a bobtná ... pro menší jednoúčelové aplikace, speciálně takové se kterými počítá napříště (třeba za dva roky) spíš zahodit než opravovat to smysl moc nedává.
Heh, "Moderni ORM frameworky" jsou dobre tak leda na vysmahnuti dema typu Pet Shop.
Protoze snaha ORM frameworku o univerzalni API k ruznym DB enginum vede zakonite ke spolecnemu jmenovateli vsech podporovanych enginu. A ze napr MSSQL donedavna nepodporoval ani takovou trivialitu jako je LIMIT/OFFSET a Hibernate pak vybiral 10 radku uprostred milionradkove tabulky jak u debilu, ze nacetl milion radku a 999990 jich zahodil.
U nejakeho eshopu bylinkovych caju s 250 polozkami je to jedno, tam je ostatne jedno jak bude architektura.
Jakmile ale potrebuju pracovat s vetsimi daty, potrebuju vyuzivat i jeji featury, jinak si z Oraclu vyrobim tupou foxku se vzdalenym pristupem.
Takze v realu skoncim s ORM frameworkem pouze za ucelem mapovani databeans a vlastni vykonny kod dela sada PLSQL procedur na miru reseneho problemu.
Postgresovsky INSERT INTO WHEN CONFLICT UPDATE, nebo Oracle MERGE INTO neudelas v ORM nijak, nebo BRUTALNE NEEFEKTIVNE.
Zrovna nedavno jsem videl selmostroj, ktery pres ORM tahal z DB desetisice radku z vice tabulek, provadel vypocty, megabajty dat litaly tam a sem po siti, pomale jak prase, IO load k nebesum.
Po nahrazeni PLSQL si tomcat stahne tu jednu vysledkou integer KPI metriku...
Přikláním se k Youdovi z pohledu programátora, který začínal na Androidu (Java pak Kotlin). Problém , je právě v tom, že udělat ORM neni jen tak a není to všude. Navíc až když to ORM bude hodně dobře udělaný, tak se to možná vyrovná kombu SQL+dynamické struktury+Replismus (Aka co se dělá v Clojure a JS).
Další podle mě důkazem, že na Javě něco smrdí je rozpad JVM ekosystemu do vice jazyků (Groovy, Java, Kotlin, Scala, Clojure). Samozřejmě důvodem, jsou i fičury jazyka, ale při pohledu do komunit nejde jen o to, liší se celkově i mentální modely vývoje SW.
Ale kdeze.
Muj argument stoji na tom, ze pokud ma LIBOVOLNY ORM fungovat jako abstraktni vrstva nad DB enginem a tedy umoznit i vymenu DB enginu aplikace, musi zkratka a proste podporovat pouze ty featury, co podporuji VSECHNY podporovane databaze.
Coz je pak v realu SELECT, JOIN, CRUD a zhasiname.
Opravdu jsem jeste nevidel ORM, ktery by treba umel napr. vyuzivat Oracle XMLFOREST, coz je ve spolupraci s XSLT sakra silny nastroj. Nebo oracle stromova hierarchie pomoci CONNECT BY PRIOR
Pak se ORM pouziva s native queries a sadou PLSQL procedur pouze za ucelem mapovani entity beans a tim konci pribeh o abstraktni vrstve nad DB enginem.
Presne tak pouzivam ORM ja.
Anebo to nekdo namatla zoufale nefektivne a pak studuje debug logy, jaky REALNY select z toho ORM zprasku vylezl, aby byl schopen proindexovat tabulky at se zbavi full scanu a nested loops query planovace.
@Youda
"Zrovna nedavno jsem videl selmostroj, ktery pres ORM tahal z DB desetisice radku z vice tabulek"
A právě proto je stále ještě potřeba programátor aby zhodnotil situaci, využil případně výhod a vyhnul se nevýhodným situacím. A proto taky AFAIK ORM Frameworky umožňují používat tzv. Native Query, zatímco můžete s výhodou používat další neměné výhody, jako např. PDO, escapování atd, atp ...
Ano, taky jsem milionkrát viděl jak někdo v cyklu tahal entitu po entitě klidně pro tisíce idček, ale takovou *** ehm můžete udělat i bez ORM. A to jsem taky viděl nejednou. Často se to stane náhodou, např. někde o 4 úrovně níž je nějaká jedna metoda která tohle způsobí, nicméně zde už je to na programátorovi a jeho zájmu o to co se děje "pod kapotou" když něco píše ...
Aha takze my pracujeme s dogmami. Ty chces ale pouzivat rucne kodovanie na vsetko a logiku kodovat v PLSQL. HAHAHA. Prezradim ti tajomstvo. Ide o to ze ten ORM framework ti v pohode vyriesi 80-95% pripadov. Ostane si urobis rucne. Bud cez bulk update, alebo native query alebo ... . Takze tolko starym dogmam.
Myslím, že se míjíte v tom, o jakých systémech píšete. U jednoduchého systému, který nepotřebuje ani pořádnou relační databázi a prostě jsou jen data z nějakého důvodu uložená v tabulkách (a používá třeba MySQL) opravdu ORM vyřeší třeba 95 % případů. Pokud ale máte velký systém, který potřebuje pořádnou relační databázi a potřebuje z ní dostat to nejlepší, ale ORM nepomůže. Protože účelem ORM je skrýt před programátorem databázovou vrstvu, zatímco v těchhle případech ji naopak potřebuje mít pevně v rukou. Pak se hodí mít nějaké mapování mezi tabulkami a objekty, ale ne ORM.
@Filip Jirsák
Tak asi by bylo nejlépe vysvětlit co je to
1) pořádná relační databáze
2) nějaké mapování mezi tabulkami a objekty, ale ne ORM
Účelem ORM není skrýt databázovou vrstvu, to je pouze teoretické zadání a často se opakuje pro základní vysvětlení v quickstart tutoriálech, ale účelem ORM je mapovat objekty na databázi. Debug a optimalizace dotazů, jejich kontrola, je stejně běžná jako u jakékoliv jiné práce s daty. Sasmozřejmě je pro některé operace výhodnější použít ORM Native Query, nicméně s těmi čísly taženými z klobouku bych se moc neoháněl.
Pokud opravdu využíváte relace, tak vlastně duplikujete to co dělá ORM. ORM Vám pro spoustu operací poskytuje automatizaci aniž byste si ji musel psát sám a dokonce můžete i využívat výhod jaké obecně veřejné knihovny/frameworky mají.
29. 1. 2020, 13:22 editováno autorem komentáře
Ne nutně je třeba mezi vrstvami budovat vlastní abstrakci. A ne ve všech jazycích přináší abstrakce nutný balast kód navíc (např. se podívejte jak realizuje "rozhraní" Dart).
Rozdělení na vrstvy má rozdíl například i (a skoro bych řekl hlavně) v tom, jakým směrem vám jdou závislosti uvnitř kódu. To vám i třeba později, když je to potřeba, umožní rozdělit monolit na více služeb bez většího refactoringu. Je to případ právě té doménové vrstvy.
Tady není asi úplně prostor to rozepisovat, ale dobře udělaná architektura práci šetří, nepřidělává. Zlepšuje orientaci v projektu, nezvyšuje složitost. Pokud se tak někde děje, je ta architektura navržená nebo naimplementovaná blbě.
K vašá otázce na "proč zrovna tolik vrstev": Onion architecture vychází ze zkušeností z mnoha projektů. Stejně jako spousta jiných architektur. Prací každého inženýra/architekta je zvážit možná řešení pro daný problém a zvolit to v danou chvíli nejlepší. Silver bullet neexistuje.