Slovník pojmů

Deptrac

Adresáře samy o sobě architekturu nevynutí. Deptrac převádí domluvené hranice mezi vrstvami do kontroly, která může selhat už v pull requestu.

Stručná definice

Kontrola toho, kdo smí záviset na kom.

Deptrac analyzuje odkazy mezi třídami, rozhraními, traity a dalšími prvky kódu. Ty nejdříve zařadí do vrstev, například Domain, Application, Infrastructure a UI. Pravidla pak řeknou, které vrstvy se smějí používat; neplatný směr závislosti vypíše jako porušení.

Nejde o nástroj, který rozhodne, zda je aplikace dobře navržená. Umožní však průběžně hlídat konkrétní rozhodnutí týmu: například aby doménové pravidlo neimportovalo ORM, controller nepracoval přímo s databázovým adaptérem a infrastruktura zůstala na okraji systému.

Použití

Kde automatické hranice dávají smysl

Kontrola se vyplatí tam, kde se aplikace rozvíjí delší dobu a nesprávný směr závislosti by postupně zhoršoval změny i testování.

  • modulární monolit s více doménovými moduly
  • Clean nebo hexagonální architektura s oddělením logiky a adaptérů
  • interní systém, kde HTTP, CLI a fronta sdílejí stejné aplikační případy
  • e-shop s odděleným katalogem, objednávkami, skladem a integracemi
  • omezení přímého používání frameworku nebo vybraných Composer balíčků mimo infrastrukturu
  • CI kontrola, že nový pull request neobchází domluvené hranice

Praktický příklad

Čtyři vrstvy importu objednávky

V modulu objednávek drží Domain pravidla a hodnotové objekty. Application obsahuje případ použití ImportMarketplaceOrder a jeho port pro uložení objednávky. Infrastructure implementuje tento port přes databázi nebo HTTP klienta. UI přijme HTTP požadavek nebo CLI příkaz a předá jej aplikační vrstvě.

Pokud by controller začal přímo volat Doctrine repository, nebo Domain importoval Laravel či Symfony třídu, Deptrac může změnu odmítnout. Není tím potvrzeno, že import funguje; je pouze ověřeno, že se neobešla zvolená hranice.

deptrac:
  paths: [./src]
  layers:
    - name: Domain
      collectors: [{ type: classLike, value: '^App\\Domain\\.*' }]
    - name: Application
      collectors: [{ type: classLike, value: '^App\\Application\\.*' }]
    - name: Infrastructure
      collectors: [{ type: classLike, value: '^App\\Infrastructure\\.*' }]
    - name: UI
      collectors: [{ type: classLike, value: '^App\\UI\\.*' }]
  ruleset:
    Domain: ~
    Application: [Domain]
    Infrastructure: [Application, Domain]
    UI: [Application]

Jak funguje

Od kódu k architektonickému pravidlu

Konfigurace má popsat skutečnou hranici aplikace, ne jen mechanicky kopírovat názvy adresářů.

  1. Cesty Deptrac načte určené adresáře a sestaví mapu závislostí mezi prvky PHP kódu.
  2. Collectory Collector rozhodne, které prvky patří do vrstvy; může vybírat například podle plného názvu třídy, adresáře, atributu, rozhraní nebo Composer balíčku.
  3. Vrstvy Pojmenované skupiny vyjadřují pohled na aplikaci. Jeden prvek může podle konfigurace patřit i do více vrstev, což je důvod kontrolovat výstup a varování.
  4. Ruleset Pravidla povolí konkrétní směr závislostí. Závislost mezi vrstvami je ve výchozím stavu zakázaná, dokud ji ruleset nepovolí.
  5. Report a CI Analýza ukáže soubor, řádek a nepovolený směr. CI pak může blokovat nová porušení před mergem.

Hlavní pojmy

Vrstvy, collectory a pravidla

Deptrac nekontroluje jednu univerzální architekturu. Kontroluje model, který aplikace sama popíše.

Layers

Vrstvy jsou skupiny prvků kódu, například Domain nebo UI. Nejsou automaticky stejné jako adresáře, i když je adresář často praktickým výchozím bodem.

Collectors

Collectory přiřazují prvky do vrstvy. Běžný classLike collector porovnává plně kvalifikovaný název; directory sleduje cestu souboru a composer může vymezit používání balíčku.

Ruleset

Ruleset vyjadřuje povolené závislosti. Application může znát Domain; Infrastructure může implementovat port definovaný v Application; UI má volat Application, ne databázový adaptér.

Porušení a uncovered

Porušení je nepovolený odkaz mezi vrstvami. Uncovered závislost znamená, že analyzovaný prvek odkazuje na třídu, která není přiřazena k žádné vrstvě; nejde sama o sobě o porušení rulesetu.

Vztah k ostatním kontrolám

Jiná otázka než PHPStan, PHPUnit nebo DI

Tyto nástroje se doplňují, ale každý zachycuje jiný typ rizika.

Deptrac a PHPStan
PHPStan ověřuje typy, neplatná volání a kontrakty jednotlivých výrazů. Deptrac ověřuje, zda je vůbec přípustné, aby třída z jedné vrstvy používala jinou vrstvu.
Deptrac a PHPUnit
PHPUnit aplikaci spouští v testovacím scénáři a ověřuje chování. Deptrac kód nespouští a neprokazuje funkčnost use casu.
Deptrac a dependency injection
DI je runtime způsob sestavení objektů. Deptrac sleduje statické odkazy v kódu; správně injektovaná služba může stále porušovat architektonickou hranici.
Diagramy
Formáttery mohou vytvořit například Graphviz nebo Mermaid výstup. Diagram pomáhá architekturu prohlédnout, ale pravidla v CI jsou to, co ji průběžně vynucuje.

Výhody a omezení

Ochrana hranic, ne náhrada návrhu

Přínosy

  • architektonický úmysl je čitelný jako verzovaná konfigurace
  • porušení se objeví u konkrétní změny, ne až při obtížném refaktoringu
  • pomáhá zachovat nezávislost modulů a doménové logiky na frameworku
  • stejná kontrola se opakuje lokálně i v CI

Omezení a časté chyby

  • zelený report neříká, zda vrstvy dávají businessově smysl
  • příliš obecné regulární výrazy a vrstvy mohou vytvářet falešný pocit kontroly
  • složitá konfigurace a mnoho výjimek mohou být dražší než chráněná část aplikace
  • adresář Domain bez skutečných pravidel není automaticky doménový model

Hranice použití

Pravidla mají růst spolu se skutečnou složitostí projektu.

Malý skript nebo jednoduchý administrativní formulář nepotřebuje čtyři vrstvy jen proto, aby prošel Deptracem. U dlouhodobého modulu s externími API, frontou, databází a více vstupními body se naopak vyplatí chránit, aby technické detaily nepronikaly do aplikační a doménové logiky.

Pro starší aplikaci lze známá porušení dočasně vynechat pomocí skip_violations nebo vygenerované baseline. Výjimky mají mít důvod a vlastníka; jejich opakované rozšiřování bez odstraňování znamená, že CI již nechrání novou změnu dostatečně.

Na co myslet

Udržovat pravidla jako součást aplikace

Užitečný report je konkrétní, srozumitelný týmu a vychází z reálného směru závislostí.

  • začít několika významnými hranicemi místo kompletní mapy všech tříd
  • pojmenovat vrstvy podle odpovědnosti, ne podle módního vzoru
  • reportovat uncovered závislosti a rozhodovat, zda je třeba je pokrýt
  • nechat Deptrac běžet v CI spolu s testy a typovou analýzou
  • výjimky a baseline pravidelně zmenšovat a kontrolovat při review

Časté otázky

Co Deptrac ověřuje

Nahradí Deptrac PHPStan nebo PHPUnit?

Ne. PHPStan hledá typové a kontraktní chyby, PHPUnit ověřuje chování spuštěné aplikace. Deptrac kontroluje jen povolený směr závislostí mezi vrstvami.

Je Deptrac nutný pro každou PHP aplikaci?

Ne. Největší přínos má u dlouhodobě rozvíjených modulů s jasně oddělenými odpovědnostmi. U malého, přímočarého projektu může být konfigurace zbytečná režie.

Stačí rozdělit třídy do adresářů?

Ne. Adresář je organizační pomůcka, ale bez rulesetu nic nebrání controlleru importovat infrastrukturní repository nebo doméně použít frameworkovou třídu.

Jsou baseline a skip_violations chyba?

Ne nutně. U existujícího projektu dovolí zavést kontrolu postupně. Musí ale být konkrétní, zdůvodněné a postupně se zmenšovat; jinak jen skrývají porušení.

Jak architektonické hranice používám v praxi

Architekturu chráním jen tam, kde zjednodušuje bezpečné změny.

Ve veřejném projektu scheduling jsou moduly členěné na Domain, Application, Infrastructure a UI. Konfigurace Deptracu ověřuje vybrané závislosti; jde o konkrétní ukázku, ne univerzální šablonu pro každou aplikaci.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.