Mérnöki kézikönyv · 02 / 09 · Szoftverarchitektúra

Modern szoftverarchitektúra módszertani kézikönyv

Fejlesztőknek, CTO-knak, IT vezetőknek és AI projektet vezető üzleti vezetőknek szól, akik mérlegelve akarnak architektúrát választani, nem divatból. Minden módszernél ott a lépéssor, a megtérülés feltétele, a tipikus hiba és az AI asszisztált fejlesztésre szabott változat, a 2003 és 2026 közötti szakirodalom alapján.

Kalmár Dániel · kb. 61 perc olvasás · A sorozat része, Mérnöki kézikönyvek

Tartalom

A modern módszerek klasszikus gyökerekre épülnek. Parnas információrejtése, Dijkstra strukturált vezérlése, Conway törvénye és Brooks koncepcionális integritása részletesen a papírkorszak módszereiről szóló kézikönyvben szerepel, itt csak visszautalunk rájuk. Az alábbi módszerek a 2026 októberi állapot szerinti kiadásokra épülnek, a teljes lista a Források alatt található.

1. Az architektúra törvényei és alapfogalmai (Richards és Ford)

1.1 A törvények

Az első törvény. A szoftverarchitektúrában minden kompromisszum. Ehhez a szerzők egy következményt is fűznek, hogy ha valaki azt hiszi, talált valamit, ami nem kompromisszum, akkor valószínűleg csak még nem azonosította, mivel fizet érte.

A második törvény. Fontosabb a miért, mint a hogyan. Egy diagram megmutatja, hogyan néz ki a rendszer, de azt nem, miért ilyen. Ezért kell az ADR (7.3 pont).

A 2. kiadás kiegészítése. A legtöbb architekturális döntés egy skálán mozog két szélsőség között, nem bináris választás. Monolit és microservices között ott van a moduláris monolit és a service based architektúra. Szinkron és aszinkron hívás között pedig ott a kérés és válasz üzenetsoron keresztül.

Gyakorlati alkalmazás. Minden architekturális javaslat mellé odaírjuk a költségét is. Egy javaslat költség nélkül marketing, nem mérnöki munka.

1.2 Architekturális jellemzők azonosítása és priorizálása

Az architekturális jellemző (architectural characteristic, a régebbi irodalomban nem funkcionális követelmény vagy quality attribute) akkor számít, ha három feltétel teljesül. Nem a domain funkciója, befolyásolja a szerkezetet, és kritikus vagy fontos az alkalmazás sikere szempontjából.

Kategóriák a 2. kiadás szerint

KategóriaPéldák
Működési (operational)availability, performance, scalability, elasticity, reliability, recoverability
Szerkezeti (structural)modularity, maintainability, extensibility, testability, deployability, portability
Felhő jellemzőkon demand skálázás, szolgáltatói függés, zónák közti redundancia
Átfogó (cross cutting)security, privacy, accessibility, legal, auditability, usability

Lépések

  1. A domain szempontok kigyűjtése. A megrendelő üzleti nyelvén (gyors piacra jutás, felhasználói elégedettség, versenyelőny, költségcsökkentés, összeolvadás és felvásárlás).
  2. Fordítás jellemzőkre. Gyors piacra jutás jelentése agility, ami összetett jellemző (testability plus deployability plus modularity). Felvásárlás jelentése interoperability és extensibility.
  3. Explicit jellemzők a követelményekből. Például 1000 egyidejű felhasználó, ez scalability. Napi egyszeri csúcs (Black Friday, jegyértékesítés) pedig elasticity.
  4. Az implicit jellemzők megnevezése. Amit senki nem mond ki, de mindenki elvár (availability, security, alap performance).
  5. Legfeljebb hét jelölt marad. Ennél több jellemzőre tervezett rendszer általános és ezért semmire nem jó.
  6. A top három kiválasztása. Mind a hetet nem kell sorrendbe tenni, mert azon a csapat sosem egyezik meg. A három legfontosabban viszont egyet kell érteni.
  7. Mérhető cél mindegyikhez. Ami nem mérhető, arra fitness function sem írható (4. pont).

Sablon (architektúra jellemző lap)

## Architekturális jellemzők. <projekt>
| Jellemző | Forrás (domain szempont vagy követelmény) | Cél, mérőszám | Top 3? |
|----------|-------------------------------------------|---------------|--------|
| auditability | GDPR, ügyféladat kezelés | minden írás naplózva, ki, mit, mikor | igen |
| simplicity | egy fejlesztő plus AI | egy deploy egység, egy adatbázis | igen |
| availability | belső eszköz, munkaidőben | 99,5% munkaidőben | nem |
Implicit: security, alap performance (p95 < 500 ms)
Szándékosan NEM optimalizált: elasticity, multi region

Tipikus hibák

AI asszisztált fejlesztésnél. A generált kód implicit módon mindig a gyors elkészülésre optimalizál. Ha a projekt jellemzői közt ott van az auditability vagy a privacy, ezt a promptba és az AI asszisztens projektszintű instrukciós fájljába (például AGENTS.md vagy CLAUDE.md) is be kell írni, különben nem lesz benne a kódban. A témáról bővebben az AI ügynökökről és a vibecodingról szóló kézikönyv ír.

1.3 Architecture quantum

Egy architecture quantum a rendszer önállóan telepíthető darabja, amelynek magas a funkcionális kohéziója, magas a statikus csatolása (közös adatbázis, közös könyvtár, közös broker), és szinkron a dinamikus csatolása (futás közben szinkron hívással várnak egymásra). A Hard Parts finomítja a fogalmat, és a dinamikus csatolást három dimenzió mentén vizsgálja (kommunikáció, konzisztencia, koordináció).

Miért hasznos. Az architekturális jellemzők quantumonként eltérhetnek. Ha a rendelésfelvételnek elasticity kell, a riportolásnak nem, akkor két quantum indokolt. Amikor az egész rendszernek ugyanazok a jellemzői, egy quantum is elég, és akkor egy deploy egységről beszélünk.

A quantumok megszámolása

  1. Felrajzoljuk a deploy egységeket.
  2. Összehúzzuk azokat, amelyek közös adatbázist használnak. Egy közös adatbázis egy quantumba köti őket, akárhány szolgáltatásra van bontva a kód.
  3. Összehúzzuk azokat is, amelyek szinkron hívással egymásra várnak egy felhasználói kérésen belül.
  4. Ami külön marad, az egy-egy quantum.

Tipikus hiba. A disztribuált monolit. Tíz szolgáltatás, egy adatbázis, szinkron hívásláncok. Ez egy quantum tíz deploy egység költségével.

1.4 Komponensek meghatározása

A komponens a logikai építőelem (Javában csomag, TypeScriptben könyvtár vagy modul névtér), a szolgáltatás a fizikai. Előbb a logikai architektúra készül el, utána a fizikai.

Lépések (Richards és Ford ciklusa)

  1. Kezdeti komponensek azonosítása. Három megközelítés közül lehet választani. A szereplő és cselekvés (actor/actions) módszer a felhasználói szerepekből és azok tevékenységeiből indul. Workflow módszernél a fő üzleti folyamatok lépéssora a kiindulópont. Az event storming pedig a domain eseményekből dolgozik (5.4 pont).
  2. Követelmények hozzárendelése. Minden user story egy komponenshez kerül. Ha egy komponenshez túl sok jut, túl durva. Amikor egy story három komponenst érint egyszerre, rossz a vágás.
  3. Szerepek és felelősségek elemzése. Leírható egy mondatban, mit csinál a komponens? Ha nem, darabolni kell.
  4. Jellemzők elemzése. Indokolja-e a top 3 jellemző a komponens kettévágását? Például a fizetés komponens security szempontból elkülönül.
  5. Átalakítás. Iterálunk, amíg a szerkezet stabil nem lesz.

Tipikus hiba, az entity trap. A komponenseket az adatbázis táblák köré szervezik (UserManager, OrderManager, ProductManager), amelyek CRUD műveleteket csomagolnak. Ilyenkor a viselkedés szétszóródik, a komponensnevek semmit nem mondanak a rendszerről. AI generált kódnál ez a leggyakoribb kiinduló szerkezet, mert a modell a táblákból indul ki.

Granularitási jelek. Túl durva, ha egy komponens neve általános (Manager, Service, Utils, Common), vagy ha a fájlok több mint fele független változtatásokat kap. Ellenkező irányban túl finom, ha egy komponens egyetlen függvényből áll, és minden hívása egy másik komponensbe továbbít.

1.5 Stíluskatalógus

A 2. kiadás külön tárgyalja a monolitikus stílusokat (layered, modular monolith, pipeline, microkernel) és az elosztottakat (service based, event driven, space based, orchestration driven SOA, microservices). Az alábbi értékelés 1 és 5 csillag közötti, 5 a legjobb. A számok a könyv 1. kiadásának táblázatait követik, a moduláris monolit sora viszont a 2. kiadás szövegéből becsült érték, nem a könyv szó szerinti adata. Az olcsóság oszlopban az 5 csillag a legolcsóbbat jelenti.

StílusTelepíthetőségRugalmas skálázás (elasticity)TovábbfejleszthetőségHibatűrésModularitásOlcsóságTeljesítményMegbízhatóságSkálázhatóságEgyszerűségTesztelhetőség
Layered11111523152
Modular monolith21314533143
Pipeline21313523153
Microkernel31313533143
Service based42344434334
Event driven33554353512
Space based35333154511
Orchestration driven SOA13133122411
Microservices45545124514

Stílusonként röviden

A stílusválasztás lépései

  1. Top 3 jellemző az 1.2 pont szerint.
  2. A quantumok száma az 1.3 pont szerint. Egy quantumhoz monolitikus stílus illik, többhöz elosztott.
  3. Domain vagy technikai particionálás? Ma a domain szerinti az alapértelmezés.
  4. A táblázatból azt a stílust választjuk, amely a top 3-ban nem gyenge (legalább 3 csillag), és amelynek az egyszerűsége elfogadható a csapat méretéhez.
  5. ADR rögzíti, mit adtunk fel érte.

1.6 Architekturális governance

A governance a szerzőknél nem jóváhagyó bizottság, hanem automatizált ellenőrzés. Az architektúra szabályait kóddá alakítjuk (fitness function, 4. pont), és a CI futtatja őket. A 2. kiadás a governance-t a fejlesztési folyamatba ágyazza, és külön foglalkozik azzal, hogyan mérhető a kódbázisból a modularitás (kohézió, csatolás, a fő sorozattól való távolság, Robert C. Martin absztraktság és instabilitás mérőszámai alapján).

Mérőszámok röviden

MérőszámJelentésJel
Afferent coupling (Ca)hány modul függ ettőlmagas érték, óvatos változtatás
Efferent coupling (Ce)hány modultól függ ezmagas érték, törékeny
Instabilitás I = Ce / (Ca + Ce)0 stabil, 1 instabil
Absztraktság Aabsztrakt elemek aránya
Távolság a fő sorozattól D = abs(A + I - 1)0 ideálisközel 1 érték a fájdalom zónája (konkrét és stabil) vagy a haszontalanság zónája (absztrakt és instabil)
ConnascenceMeilir Page-Jones fogalma, a csatolás fajtái név, típus, jelentés, pozíció, algoritmus, végrehajtási sorrend, időzítés, érték, identitás szerintminél gyengébb fajta és minél közelebb van egymáshoz, annál jobb

1.7 A 2. kiadás új témái

2. Minőségi attribútumok, taktikák, ATAM (Bass, Clements, Kazman)

A SEI iskola a 4. kiadásban tíz minőségi attribútumot tárgyal külön fejezetben. Ezek az availability, deployability, energy efficiency, integrability, modifiability, performance, safety, security, testability és usability. Az energy efficiency és a safety új a korábbi kiadásokhoz képest.

2.1 A minőségi attribútum forgatókönyv hat része

Egy jellemző akkor használható, ha forgatókönyvvé alakítjuk. A forgatókönyv hat részből áll.

RészKérdésPélda (availability)
Forrás (source)ki vagy mi váltja kikülső fizetési szolgáltató
Inger (stimulus)mi történik30 másodpercig nem válaszol
Környezet (environment)milyen állapotban van a rendszernormál üzem, munkaidő
Érintett elem (artifact)mire hatrendelés leadás szolgáltatás
Válasz (response)mit tesz a rendszera rendelést függőben rögzíti, a felhasználót értesíti
Válaszmérték (response measure)hogyan mérjüka felhasználó 2 másodpercen belül választ kap, adatvesztés nulla

Gyakorlat. Minden top 3 jellemzőhöz legalább egy ilyen sor tartozik. Az AI asszisztensnek ez kiváló bemenet, mert a válaszmértékből közvetlenül teszt vagy fitness function írható.

2.2 Taktikák

A taktika egy tervezési döntés, amely egyetlen minőségi attribútum válaszát befolyásolja. Ezzel szemben a minta (pattern) több taktika csomagja. A fontosabb taktikacsaládokat a táblázat foglalja össze.

AttribútumTaktikacsoportPéldák
Availabilityhibafelismerésheartbeat, ping/echo, monitor, időbélyeg, önteszt
Availabilityhelyreállításaktív és passzív redundancia, rollback, retry, degradáció, újraindítás
Availabilitymegelőzésszolgáltatás kivonása, tranzakció, prediktív modell
Modifiabilityméret csökkentésemodul szétvágása
Modifiabilitykohézió növeléseszemantikai koherencia növelése, felelősség áthelyezése
Modifiabilitycsatolás csökkentésebeágyazás, közvetítő, absztrakt közös szolgáltatás, korlátozott függőségek
Modifiabilitykésleltetett kötéskonfiguráció, plugin, futásidejű regisztráció
Performanceerőforrás igény szabályozásamintavételezés, kérések priorizálása, rate limit, hatékonyabb algoritmus
Performanceerőforrások kezelésepárhuzamosítás, cache, replikák, ütemezés
Securitytámadás felismerésebehatolás érzékelés, üzenet integritás
Securitytámadásnak ellenállásazonosítás, hitelesítés, jogosultság, titkosítás, korlátozott kitettség
Securityreagálás, helyreállításhozzáférés visszavonása, zárolás, audit napló
Testabilitymegfigyelhetőség és vezérlésspeciális interfészek, rögzítés és visszajátszás, állapot lokalizálás, sandbox
Deployabilitypipeline kezelésskálázott rollout, rollback, feature toggle

Használat. A forgatókönyv válaszmértékéhez megkeressük a taktikacsoportot, onnan egy-két konkrét taktikát választunk, és ADR-ben rögzítjük, melyik másik attribútumot rontja. Jó példa a cache, amely javítja a performance-t, de rontja a konzisztenciát és a modifiability-t.

2.3 Utility tree

Fa szerkezet. A gyökér az utility (a rendszer hasznossága), alatta a minőségi attribútumok, azok alatt finomítások, a leveleken konkrét forgatókönyvek. Minden levél két értéket kap (H, M, L), az üzleti fontosságot és a megvalósítás nehézségét.

Utility
├── Performance
│   └── Kereséskor válaszidő
│       └── (H,M) 10 000 termék között a keresés p95 < 300 ms normál terhelésnél
├── Security
│   └── Adathozzáférés
│       └── (H,H) Másik bérlő adatai semmilyen API hívással nem érhetők el
└── Modifiability
    └── Új fizetési szolgáltató
        └── (M,L) Új szolgáltató bekötése 2 napon belül, a rendelés modul változatlan

A (H,H) levelek a legkockázatosabbak, ezekkel foglalkozunk elsőként.

2.4 Az ATAM lépései

Az Architecture Tradeoff Analysis Method kilenc lépés négy fázisban. A 0. fázis a partnerség és előkészítés, a 3. a követés.

FázisLépésTartalom
1. Értékelés1ATAM bemutatása
2Üzleti célok bemutatása (business drivers)
3Architektúra bemutatása
4Architekturális megközelítések azonosítása
5Utility tree felépítése
6Megközelítések elemzése a magas prioritású forgatókönyveken
2. Értékelés bővített körrel7Forgatókönyvek ötletelése és priorizálása az érintettekkel
8Megközelítések újraelemzése az új forgatókönyveken
9Eredmények bemutatása

Kimenetek. Kockázatok (risk), nem kockázatok (non risk), érzékenységi pontok (sensitivity point, ahol egy paraméter erősen befolyásol egy attribútumot), kompromisszumpontok (tradeoff point, ahol egy döntés több attribútumot ellentétesen érint), kockázati témák.

Kis csapatnak vagy egy fejlesztőnek. A teljes ATAM napokig tart, a mini változat egy óra. Utility tree tíz levéllel, a (H,H) és (H,M) leveleken végigmegyünk a 6. lépésen, a kimenet egy kockázatlista, abból születnek az ADR-ek. Ez a mini változat egy nagyobb refaktor vagy egy új rendszer előtt mindig belefér, és AI asszisztenssel a forgatókönyvek első vázlata gyorsan összeáll.

3. Software Architecture: The Hard Parts

A könyv alapgondolata szerint elosztott rendszerben nincsenek legjobb gyakorlatok, csak kompromisszumok, és ezek elemzését kell megtanulni. Egy kitalált cég (Sysops Squad) migrációján vezet végig.

3.1 Szolgáltatás granularitás, disintegrators és integrators

Mekkora legyen egy szolgáltatás? Két erőcsoport hat egymás ellen.

Szétbontó erők (granularity disintegrators)

ErőKérdés
Szolgáltatás hatóköre és funkciójaEgy jól körülhatárolt dolgot csinál, vagy több, egymástól független dolgot?
Kód volatilitásA kód egy része sokkal gyakrabban változik, mint a többi?
Skálázhatóság és áteresztőképességEgyes részeknek eltérő skálázás kell?
HibatűrésEgy rész hibája ne döntse le a többit?
BiztonságEgyes részek érzékenyebb adatot kezelnek, eltérő hozzáféréssel?
BővíthetőségTervezetten bővülni fog újabb változatokkal (új fizetési mód)?

Összetartó erők (granularity integrators)

ErőKérdés
Adatbázis tranzakciókKell ACID tranzakció a részek között?
Munkafolyamat és koreográfiaAnnyit hívnák egymást, hogy a késleltetés és a hibalehetőség elfogadhatatlan?
Közös kódJelentős közös üzleti logikát használnak, ami együtt változik?
AdatkapcsolatokAz adataik szorosan összefüggnek (közös kulcsok, join)?

Lépések. Egy táblázatba felírjuk a jelölt szétvágást, és minden erőhöz beírjuk, hogy hat-e, és mennyire erősen. Nem a darabszám dönt, hanem az, hogy melyik erő kapcsolódik a top 3 jellemzőhöz. A döntést az üzleti oldallal együtt hozzuk, nekik is érthető nyelven. Például szétbontva gyorsabb az új fizetési mód bevezetése, de a rendelés és a fizetés között csak végső konzisztencia lesz.

3.2 Adat szétválasztás

Adat szétbontó erők (data disintegrators). Változáskezelés (egy séma változás hány szolgáltatást érint), kapcsolatkezelés (connection pool kimerülése), skálázhatóság, hibatűrés, architecture quantum (közös adatbázis egy quantumba köt), adatbázis típus optimalizálása (kulcs érték, dokumentum, gráf).

Adat összetartó erők (data integrators). Adatkapcsolatok (idegen kulcsok, nézetek, triggerek) és adatbázis tranzakciók.

A szétválasztás öt lépése a könyv szerint

  1. Adatdomainek elemzése a táblák és a kód viselkedése alapján, sémánként csoportosítva.
  2. Táblák hozzárendelése adatdomainhez (például séma per domain).
  3. Adatbázis kapcsolatok szétválasztása, minden szolgáltatás csak a saját sémáját éri el.
  4. Sémák áthelyezése külön adatbázis szerverre.
  5. Független adatbázisokra váltás.

Adathozzáférési minták más domain adatához

MintaLeírásÁra
Interservice communicationSzinkron hívás a tulajdonos szolgáltatáshozkésleltetés, rendelkezésre állás függés
Column schema replicationNéhány oszlop másolása a fogyasztóhozszinkronizálás, elavult adat
Replicated cachingMemóriában replikált cachememória, indulási idő
Data domainKözös séma több szolgáltatásnaktágabb quantum

AI asszisztált fejlesztésnél. Supabase vagy egy Postgres esetén a séma per modul (például billing, crm) olcsó első lépés. Megadja a határt, de nem kényszerít elosztott tranzakcióra. Az adatmodellezés részleteiről az adatokról és adatbázisokról szóló kézikönyv ír.

3.3 A nyolc saga típus

A Hard Parts a dinamikus csatolást három dimenzióval írja le. Ezek a kommunikáció (szinkron vagy aszinkron), a konzisztencia (atomi vagy végső) és a koordináció (orkesztrált vagy koreografált). Minden kombináció egy saga minta.

NévKommunikációKonzisztenciaKoordinációCsatolásJellemzés
Epic Sagaszinkronatomiorkesztráltnagyon magasa monolit viselkedését utánozza elosztottan, a legtöbb csapat ide tér vissza ösztönösen
Phone Tagszinkronatomikoreografáltmagasnincs koordinátor, az első szolgáltatás viszi a hibakezelést
Fairy Taleszinkronvégsőorkesztráltmagaskönnyen érthető, jó kompromisszum, gyakori
Time Travelszinkronvégsőkoreografáltközepeslánc szerű folyamatokra (pipeline) jó
Fantasy Fictionaszinkronatomiorkesztráltmagasaz aszinkronitás és az atomiság üti egymást, ritkán jó
Horror Storyaszinkronatomikoreografáltközepesa legrosszabb kombináció, atomiság koordinátor nélkül aszinkronban
Parallel Sagaaszinkronvégsőorkesztráltalacsonyjól skálázódik, összetett hibakezelés
Anthology Sagaaszinkronvégsőkoreografáltnagyon alacsonya legnagyobb skálázhatóság, a legnehezebb követni

Kiegészítő minták a sagákhoz. Kompenzáló tranzakció (a már végrehajtott lépés visszafordítása), állapotgép a sagához (a hosszú futású folyamat állapota explicit, például CREATED, PAYMENT_PENDING, PAID, FAILED), transactional outbox (az üzenet az adatbázis tranzakción belül egy outbox táblába kerül, és onnan egy külön folyamat küldi tovább, így nem fordulhat elő, hogy az írás megtörtént, de az esemény elveszett).

Döntési szabály. Ha a folyamathoz atomi konzisztencia kell, a résztvevő szolgáltatásokat nem vágjuk szét. Ahol a szétvágás elkerülhetetlen, ott végső konzisztenciával és Fairy Tale vagy Parallel mintával dolgozunk.

3.4 Szerződések (contracts)

FogalomJelentés
Szigorú szerződés (strict)séma, típus, verzió (JSON Schema, gRPC, OpenAPI)
Laza szerződés (loose)név érték párok, csak a szükséges mezőket olvassák
Stamp couplingegy nagy adatstruktúrát adunk át, amiből a fogyasztó egy mezőt használ. Fölösleges csatolás és sávszélesség
Consumer driven contractsa fogyasztók tesztként leírják, mit várnak, és a szolgáltató buildje ezeket futtatja (Pact)

Szabály. Belső modulok között lehet szigorú, típusos szerződés. Csapat vagy szervezeti határon a laza szerződés és a consumer driven tesztek csökkentik a koordinációs igényt.

3.5 A kompromisszum elemzés módszere

  1. Az összegabalyodás feltárása. Melyik rész függ melyiktől statikusan és dinamikusan.
  2. A csatolás elemzése. Statikus (közös könyvtár, közös adat) és dinamikus (hívás, konzisztencia, koordináció).
  3. A kompromisszumok értékelése. Minőségi (kvalitatív) és ahol lehet, mennyiségi összehasonlítás. A szempontlista legyen MECE (kölcsönösen kizáró, együttesen teljes).
  4. A kontextuson kívüli csapda elkerülése. Egy általános előny és hátrány lista nem dönt, csak a saját top 3 jellemzőre vetítve.
  5. Forgatókönyvek modellezése. Konkrét esetekre (új mező hozzáadása, a fizetés kiesése) mindkét változatot végigrajzoljuk.
  6. A lényeg kimondása, evangelizálás nélkül. A döntéshozónak egy mondatos következtetés kell, nem technológiai lelkesedés.

4. Fejlődőképes architektúra és fitness functions

A Building Evolutionary Architectures (2. kiadás, 2022) szerint az architektúrának a változás irányítására kell felkészülnie. Az eszköz a fitness function, egy objektív, automatizálható ellenőrzés, amely egy architekturális jellemző teljesülését méri.

4.1 Típusok

DimenzióVáltozatokPélda
Hatóköratomi (egy jellemző egy kontextusban) vagy holisztikus (több jellemző együtt)rétegfüggőség ellenőrzése, illetve biztonság és teljesítmény együtt terhelés alatt
Ütemezéstriggerelt (CI futás) vagy folyamatos (éles monitorozás)unit teszt, illetve szintetikus tranzakció élesben
Eredménystatikus (fix küszöb) vagy dinamikus (kontextusfüggő küszöb)ciklikus függőség tilos, illetve a válaszidő a terheléstől függ
Végrehajtásautomatizált vagy manuálisArchUnit szabály, illetve jogi átnézés
Időbeliségtemporálisfigyelmeztet, ha egy függőség 6 hónapja nem frissült
Szándékszándékos (tervezett) vagy emergens (később derül ki, hogy kell)
Domaindomain specifikuspénzügyi számítások pontossága, adatvédelmi szabály

A bevezetés lépései

  1. A top 3 jellemzőből és a forgatókönyvekből (2.1 pont) kiválasztjuk, amelyik automatizálható.
  2. Megírjuk a legegyszerűbb ellenőrzést, ami megbukik, ha a szabály sérül.
  3. CI-be tesszük, így a build elbukik, ha a szabály sérül.
  4. Ha egy szabályt tudatosan megszegünk, ADR-ben rögzítjük, és a fitness functionben kivételt adunk hozzá, hivatkozással.

4.2 Példák

ArchUnit (Java), rétegszabály és ciklusmentesség

@AnalyzeClasses(packages = "com.acme.shop")
class ArchitectureTest {
  @ArchTest
  static final ArchRule layers = layeredArchitecture().consideringAllDependencies()
      .layer("Web").definedBy("..web..")
      .layer("Application").definedBy("..application..")
      .layer("Domain").definedBy("..domain..")
      .layer("Infrastructure").definedBy("..infrastructure..")
      .whereLayer("Web").mayNotBeAccessedByAnyLayer()
      .whereLayer("Application").mayOnlyBeAccessedByLayers("Web")
      .whereLayer("Domain").mayOnlyBeAccessedByLayers("Application", "Infrastructure");

  @ArchTest
  static final ArchRule noCycles = slices().matching("com.acme.shop.(*)..").should().beFreeOfCycles();
}

dependency-cruiser (JavaScript, TypeScript), moduláris monolit határai

// .dependency-cruiser.cjs
module.exports = {
  forbidden: [
    { name: "no-circular", severity: "error", from: {}, to: { circular: true } },
    {
      name: "modul-csak-a-publikus-feluleten-at",
      comment: "Más modul belső fájljait nem importáljuk, csak az index.ts-t",
      severity: "error",
      from: { path: "^src/modules/([^/]+)/" },
      to: { path: "^src/modules/([^/]+)/(?!index\\.ts$)", pathNot: "^src/modules/$1/" }
    },
    {
      name: "domain-nem-fugg-infrastrukturatol",
      severity: "error",
      from: { path: "/domain/" },
      to: { path: "(/infrastructure/|node_modules/(@supabase|stripe|openai|@anthropic-ai))" }
    }
  ]
};
// futtatás: npx depcruise src --config .dependency-cruiser.cjs

További eszközök. NetArchTest és ArchUnitNET (.NET), PyTestArch és import-linter (Python), Konsist (Kotlin), eslint-plugin-boundaries (JavaScript), Nx module boundaries (monorepó), Spring Modulith (ApplicationModules.of(App.class).verify()), Packwerk (Ruby, Shopify).

Nem kód szintű fitness functionök

5. Domain Driven Design

5.1 Stratégiai tervezés (Evans 2003)

Ubiquitous language (közös nyelv). A domain szakértők és a fejlesztők ugyanazokat a szavakat használják, és ezek a szavak a kódban is megjelennek (osztálynév, függvénynév, tábla, esemény). Ha az üzlet ajánlatot mond, a kódban ne Quote legyen az egyik helyen és Offer a másikon.

Lépések

  1. Fogalomtár (glossary) a projekt gyökerében, minden kulcsfogalommal, egy mondatos definícióval.
  2. Ha egy szónak két területen két jelentése van, az két bounded context jele.
  3. A kód elnevezéseit a fogalomtárhoz igazítjuk. Egy kódgeneráló modell számára is ez a fogalomtár a legjobb bemenet a következetes elnevezéshez.

Bounded context. Az a határ, amelyen belül egy modell és annak nyelve egyértelmű. Egy ügyfél például a számlázásban adószám és számlázási cím, a támogatásban jegyek és SLA, a marketingben szegmens és hozzájárulás. Közös Customer osztály mindhárom igényt rosszul szolgálja.

Context map minták

MintaMit jelentMikor
Partnershipkét csapat közösen tervez, együtt sikerül vagy bukikszoros együttműködés, közös cél
Shared kernela modell egy kis részét közösen birtokoljákkis, stabil közös rész, jó kommunikáció
Customer suppliera fogyasztó igényeit a szolgáltató beépíti a tervezésbeupstream és downstream világos viszonnyal
Conformista fogyasztó átveszi a szolgáltató modelljét változtatás nélkülha nincs befolyás és a modell elfogadható
Anticorruption layer (ACL)fordító réteg védi a saját modellt a külső modelltőllegacy rendszer, rossz külső API, harmadik fél
Open host servicea szolgáltató jól definiált, nyilvános protokollt kínálsok fogyasztó
Published languagedokumentált közös adatformátum (például iCalendar, UBL)integráció szabványos nyelven
Separate waysnincs integráció, mindenki megoldja magánakaz integráció drágább, mint a duplikáció
Big ball of mudhatárok nélküli rész, amit körbe kell kerítenilegacy terület jelölésére

AI asszisztált fejlesztésnél az ACL a legfontosabb. Minden külső API (Stripe, számlázó, LLM szolgáltató, CRM) egy adapter mögé kerül, amely a külső modellt a saját domain típusaira fordítja. A domain kód soha nem lát Stripe objektumot.

5.2 Taktikai tervezés

ÉpítőelemLényegeEllenőrző kérdés
Entityidentitása van, ami az életciklusán át megmaradkét példány akkor is különböző, ha minden mezőjük egyezik?
Value objectidentitás nélküli, értéke határozza meg, megváltoztathatatlanMoney, EmailAddress, DateRange. Csere az új értékre, nem módosítás
Aggregatekonzisztencia határ, egy gyökér entityvelmelyik invariáns kell, hogy egy tranzakción belül mindig igaz legyen?
Repositoryaggregátum szintű gyűjtemény absztrakcióaggregátum gyökérenként egy, nem táblánként
Domain serviceolyan művelet, ami egyik entityhez sem tartozik természetesenpéldául árfolyam konverzió két érték között
Domain eventa domainben megtörtént, múlt idejű tényRendelesLeadva, SzamlaKiallitva
Factorybonyolult létrehozás elrejtéseamikor a konstruktor nem tudja garantálni az invariánsokat

Vernon négy aggregátum szabálya

  1. Az igazi invariánsokat konzisztencia határon belül modellezzük.
  2. Kicsi aggregátumokat tervezünk. A nagy aggregátum zárolási ütközést és lassú betöltést okoz.
  3. Más aggregátumokra csak azonosítóval hivatkozunk, objektum referenciával nem.
  4. Az aggregátum határon kívül végső konzisztencia érvényes (domain eventtel).

Egy tranzakció egy aggregátumot módosít. Ha egy felhasználói műveletnek kettőt kell módosítania, az egyik szinkron, a másik eseményre reagál.

// Value object
export class Money {
  private constructor(readonly amount: bigint, readonly currency: "HUF" | "EUR") {}
  static of(amount: bigint, currency: "HUF" | "EUR") {
    if (amount < 0n) throw new Error("Negatív összeg");
    return new Money(amount, currency);
  }
  add(o: Money) {
    if (o.currency !== this.currency) throw new Error("Eltérő pénznem");
    return new Money(this.amount + o.amount, this.currency);
  }
}

// Aggregate gyökér, az invariánst ő védi
export class Order {
  private lines: OrderLine[] = [];
  private status: "draft" | "placed" = "draft";
  readonly events: DomainEvent[] = [];
  constructor(readonly id: OrderId, readonly customerId: CustomerId) {} // más aggregátum csak ID

  addLine(productId: ProductId, qty: number, price: Money) {
    if (this.status !== "draft") throw new Error("Leadott rendelés nem módosítható");
    this.lines.push(new OrderLine(productId, qty, price));
  }
  place() {
    if (this.lines.length === 0) throw new Error("Üres rendelés nem adható le");
    this.status = "placed";
    this.events.push({ type: "OrderPlaced", orderId: this.id, at: new Date() });
  }
}

Tipikus hibák. Anemic domain model (Fowler kifejezése), amikor az entity csak getter és setter, a logika a service osztályokban van. CRUD alkalmazásnál ez önmagában nem bűn, de a core domainben a szabályok szétszóródását okozza. Gyakori még a táblánkénti repository, a fél adatbázist betöltő nagy aggregátum, és a domain event, amely valójában parancs (SendEmail esemény néven).

5.3 Khononov, subdomain típusok és döntési heurisztika

SubdomainJellemzőPéldaJavasolt megoldás
Coreversenyelőny, bonyolult, gyakran változikajánlatkalkulátor egyedi szabályokkal, ajánlómotorházon belül, a legjobb emberrel, gazdag domain modellel
Supportingszükséges, de nem különböztet meg, egyszerűbelső admin, egyedi riportegyszerű megoldás, akár kiszervezve vagy low code
Genericmindenki ugyanígy oldja meghitelesítés, számlázás, email küldés, fizetésmegvásárolt vagy kész szolgáltatás

Döntési fa az üzleti logika mintájához

  1. Generic subdomain? Kész szolgáltatás (Supabase Auth, Stripe, Számlázz.hu API).
  2. Egyszerű adatbevitel és lekérdezés, kevés szabály? Transaction script (egy függvény egy üzleti művelet) vagy active record.
  3. Pénzt kezel, auditálni kell, vagy az állapotváltozások története üzleti érték? Event sourced domain model.
  4. Bonyolult üzleti szabályok, invariánsok? Domain model (az 5.2 pont építőelemei).

Az architektúra minta ehhez igazítva. Transaction script és active record mellé layered architektúra elég. Domain model mellé ports and adapters illik, event sourced domain model mellé CQRS.

A tesztelési stratégia ehhez igazítva. Domain modelnél tesztpiramis (sok unit teszt az aggregátumokon). Active recordnál gyémánt, ott az integrációs tesztek a legfontosabbak. Transaction scriptnél fordított piramis (főleg végponttól végpontig tartó tesztek).

Bounded context határ heurisztika. A bounded context nem feltétlenül egyezik a subdomainnel. Bizonytalan helyzetben szélesebb határral érdemes kezdeni, és akkor vágni szét, amikor a modell megérik. A core subdomaint érdemes a saját kontextusában tartani.

5.4 Event Storming (Brandolini)

Workshop technika, ahol a domain eseményeket egy hosszú papírfalon, színes cetlikkel rakják idősorba. A Big Picture változat a teljes üzletet, a Process Level egy folyamatot tár fel, a Software Design szint pedig az aggregátumokat és a bounded contexteket.

Lépések (Khononov tíz lépéses leírása szerint)

  1. Strukturálatlan feltárás. Mindenki narancs cetlire írja a domain eseményeket, múlt időben (Ajánlat elküldve, Szerződés aláírva).
  2. Idősor. Az eseményeket balról jobbra időrendbe rakják, a duplikátumokat összevonják.
  3. Fájdalompontok. Lila vagy rózsaszín cetli (hot spot) a vitatott, bizonytalan, problémás helyekre.
  4. Kulcsesemények (pivotal events). A folyamat fázisait elválasztó események, függőleges vonallal jelölve.
  5. Parancsok. Kék cetli, ami kiváltja az eseményt (Ajánlat elküldése), mellé sárga kis cetli a szereplővel.
  6. Szabályok (policy). Lila cetli, automatikus reakció egy eseményre (amikor a szerződés aláírva, akkor számla kiállítása).
  7. Olvasási modellek. Zöld cetli, az az adat, amit a szereplő lát, amikor dönt.
  8. Külső rendszerek. Rózsaszín cetli, amelyek parancsot adnak vagy eseményt kapnak.
  9. Aggregátumok. Nagy sárga cetli, amely a parancsokat fogadja és az eseményeket kibocsátja.
  10. Bounded contextek. Az összetartozó aggregátumok és események köré húzott határ.

Kis csapatos változat AI asszisztenssel. Az AI asszisztens egy beszélgetés átiratából vagy egy meglévő folyamatleírásból eseménylistát állít össze (múlt idejű igék, időrendben), ezt a domain szakértő javítja. Utána a modell parancsokat, szabályokat és aggregátum jelölteket rendel az eseményekhez egy táblázatban. A hot spotok listája a nyitott kérdések listája, ezekre addig nem generálunk kódot, amíg el nem dőlnek.

| # | Esemény (múlt idő) | Parancs | Szereplő vagy szabály | Aggregátum | Olvasási modell | Hot spot |
|---|--------------------|---------|-----------------------|------------|-----------------|----------|
| 1 | Érdeklődés beérkezett | Űrlap beküldése | Látogató | Lead | | |
| 2 | Cég átvilágítva | Átvilágítás indítása | szabály, új lead esetén | Lead | cégadat | ki dönt, ha negatív? |
| 3 | Ajánlat elküldve | Ajánlat küldése | Tanácsadó | Ajánlat | ármátrix | |

6. Hexagonal, Onion, Clean Architecture

6.1 Közös mag, a függőségi szabály

Mindhárom ugyanazt mondja más ábrával. A forráskód függőségei csak befelé, a domain felé mutathatnak, ezért a domain nem tud az adatbázisról, a webes keretrendszerről, a külső API-ról. Kifelé portokon (interfészeken) keresztül kommunikál, amelyeket a domain vagy az alkalmazási réteg határoz meg, és adapterek valósítanak meg.

VáltozatKépHangsúly
Hexagonal, Ports and Adapters (Cockburn 2005)hatszög, rajta portok, kívül adapterekdriving (elsődleges, például HTTP, CLI, teszt) és driven (másodlagos, például DB, email) adapterek szimmetriája
Onion (Palermo 2008)koncentrikus körök, domain model, domain services, application services, infrastruktúraaz infrastruktúra a legkülső héj
Clean Architecture (Martin 2012)körök, entities, use cases, interface adapters, frameworks and driversuse case mint központi egység, a keretrendszer részletkérdés

Könyvtárszerkezet egy moduláris monolitban, belül ports and adapters szerkezettel (TypeScript)

src/
  modules/
    ajanlat/
      index.ts                 # a modul nyilvános felülete, más modul csak ezt importálja
      domain/
        ajanlat.ts             # aggregate, value objectek, invariánsok
        events.ts
      application/
        ajanlat-kuldese.ts     # use case
        ports.ts               # interface AjanlatRepository, interface EmailKuldo
      infrastructure/
        supabase-ajanlat-repository.ts
        resend-email-kuldo.ts
      http/
        routes.ts              # driving adapter
    szamlazas/
      ...
  shared/
    kernel/                    # nagyon kicsi, stabil közös típusok (Money, Id)
  main.ts                      # composition root, itt kötjük össze a portot az adapterrel
// application/ports.ts
export interface EmailKuldo { kuld(cimzett: string, targy: string, html: string): Promise<void> }

// application/ajanlat-kuldese.ts
export const ajanlatKuldese = (deps: { repo: AjanlatRepository; email: EmailKuldo }) =>
  async (id: AjanlatId) => {
    const a = await deps.repo.get(id);
    a.kuldes();                                  // invariáns a domainben
    await deps.repo.save(a);
    await deps.email.kuld(a.cimzett, a.targy(), a.html());
  };

6.2 Mikor túlzás

Mikor éri meg. Core subdomain, bonyolult invariánsok, legalább két driving adapter (HTTP és háttérfeladat, vagy HTTP és MCP szerver), reális szolgáltatócsere, vagy az az igény, hogy a domain logikát gyors, adatbázis nélküli unit tesztek fedjék le.

Pragmatikus köztes út. A domain és a külső szolgáltatások közé mindig kerül egy adapter (Parnas információrejtése, ACL), de a belső rétegeket nem bontjuk tovább, amíg nincs rá ok. AI asszisztált fejlesztésnél ez a mélység szinte mindig elég.

7. Dokumentálás, C4, arc42, ADR

7.1 C4 modell (Simon Brown)

Négy nagyítási szint, mint egy térképen.

SzintMit mutatKinekKötelező?
1. System Contexta rendszer, a felhasználói és a külső rendszerekmindenki, üzleti oldal ismindig
2. Containerfuttatható vagy adattároló egységek (web app, API, adatbázis, edge function, üzenetsor) és a köztük lévő protokollokfejlesztők, üzemeltetésmindig
3. Componentegy container belső komponenseifejlesztőkha a container bonyolult
4. Codeosztálydiagramritkánszinte soha, a kód maga a dokumentáció

Kiegészítő diagram a System Landscape (a cég összes rendszere), a Dynamic (egy forgatókönyv lépései) és a Deployment (melyik container hol fut).

Jelölési szabályok. Minden doboznak legyen típusa és technológiája. A nyilak egyirányúak, felirattal (mit és hogyan, például Számlát kér, HTTPS JSON). Jelmagyarázat is kell, a diagramnak pedig címe és hatóköre.

Diagram mint kód (Structurizr DSL)

workspace {
  model {
    tanacsado = person "Tanácsadó"
    ugyfel = person "Ügyfél"
    crm = softwareSystem "Ajánlatkezelő CRM" {
      web = container "Web app" "Next.js"
      db = container "Adatbázis" "Supabase Postgres" { tags "Database" }
      fn = container "Edge functions" "Deno"
    }
    szamlazo = softwareSystem "Számlázó szolgáltatás" { tags "External" }
    tanacsado -> web "Kezeli az ajánlatokat" "HTTPS"
    ugyfel -> web "Elfogadja az ajánlatot" "HTTPS"
    web -> db "Olvas, ír" "PostgREST, RLS"
    fn -> szamlazo "Számlát állít ki" "HTTPS JSON"
  }
  views { systemContext crm { include * autolayout lr } container crm { include * autolayout lr } }
}

Structurizr nélkül a Mermaid C4 szintaxisa (C4Context, C4Container) is renderelhető markdownban.

7.2 arc42

Tizenkét szakaszos sablon. Nem kell mindet kitölteni, egy kis projektnek a vastagon jelöltek elegendők.

#SzakaszTartalom
1Bevezetés és célokfeladat, top 3 minőségi cél, érintettek
2Kényszerektechnikai, szervezeti, jogi korlátok
3Kontextus és hatókörC4 System Context
4Megoldási stratégiaa kulcsdöntések egy oldalon
5Építőelem nézetC4 Container és Component
6Futásidejű nézetfő forgatókönyvek szekvenciái
7Telepítési nézetinfrastruktúra
8Átfogó koncepciókhibakezelés, naplózás, biztonság, i18n
9Architekturális döntésekADR lista hivatkozással
10Minőségi követelményekutility tree, forgatókönyvek
11Kockázatok és technikai adósság
12Fogalomtárubiquitous language

7.3 Architecture Decision Record

Mikor kell ADR. Ha a döntést nehéz visszafordítani (adatbázis, hitelesítés módja, bérlőelválasztás modellje), ha több értelmes alternatíva volt, ha egy szabályt tudatosan megszegünk, vagy ha egy jövőbeli olvasó (új kolléga, egy új AI munkamenet) azt kérdezné, miért így van ez.

Nygard sablon (2011)

# ADR-0007. Bérlőelválasztás sor szintű biztonsággal (RLS) egy adatbázisban

## Állapot
Elfogadva, 2026-10-20

## Kontextus
Több ügyfél adata kerül egy rendszerbe. Egy ember üzemelteti. Az ügyfelek száma 50 alatt.

## Döntés
Egy Postgres adatbázis, minden bérlőhöz tartozó táblán tenant_id oszlop és RLS policy.
Bérlőnként külön séma vagy adatbázis nem lesz.

## Következmények
+ Egy migráció, egy biztonsági mentés, olcsó üzemeltetés.
- Egy hibás policy minden bérlőt érint, ezért CI fitness function ellenőrzi, hogy minden táblán be van kapcsolva az RLS.
- Bérlőnkénti visszaállítás csak logikai exporttal megy.

A lehetséges állapotok Javasolt, Elfogadva, Elvetve, Elavult és Felváltotta ADR-XXXX. Az ADR megváltoztathatatlan. Ha a döntés változik, új ADR készül, ami felváltja a régit.

MADR 4.0 sablon (bővebb, ha alternatívákat kell összevetni)

# <rövid cím, a megoldott probléma és a választott megoldás>
## Context and Problem Statement
## Decision Drivers
## Considered Options
## Decision Outcome
Chosen option: "...", because ...
### Consequences
### Confirmation          <- hogyan ellenőrizzük, hogy betartják (fitness function, review)
## Pros and Cons of the Options
## More Information

Hely és eszköz. Sorszámozott markdown fájlok a kód mellett, verziókezelve (például docs/adr/0001-cim.md). Eszköz lehet az adr-tools vagy a log4brains, de egy markdown fájl is elég.

8. Stabilitás, Release It! (Nygard, 2. kiadás 2018)

Az alaptétel szerint minden integrációs pont előbb-utóbb meghibásodik, és a rendszer túlélése azon múlik, megállítjuk-e a hiba terjedését.

8.1 Stabilitási antiminták

AntimintaMi történikFelismerés
Integration pointsminden külső hívás (HTTP, DB, socket) hibaforrás, beleértve a lassú választ ishívás timeout nélkül
Chain reactionsegy példány kiesése után a többire nagyobb terhelés jut, és sorban dőlnek elmemóriaszivárgás, ami terheléssel gyorsul
Cascading failuresegy réteg hibája felfelé terjed a hívókraszinkron hívásláncok védelem nélkül
Usersa felhasználók száma, viselkedése, a botok és a rosszindulatú forgalommunkamenet memóriában, korlátlan feltöltés
Blocked threadsa szálak vagy kapcsolatok elfogynak, mert valamire örökké várnakconnection pool kimerülés
Self denial attackssaját marketing kampány vagy kupon dönti le a rendszertelőre nem jelzett akciók
Scaling effectsami 2 példánynál működik, 50-nél nem (példányok közti közvetlen kapcsolatok, közös erőforrás)O(n négyzet) kommunikáció
Unbalanced capacitiesa front sokkal többet bír, mint a háttéra háttérszolgáltatás kisebb, mint a hívói
Dogpilesok kliens egyszerre indul (cache lejárat, cron egész órakor, újraindítás után)szinkronizált retry
Force multiplierautomatizálás, ami a hibát felnagyítja (autoscaler, konfigurációkezelő)ellenőrzés nélküli automatikus beavatkozás
Slow responsesa lassú válasz rosszabb, mint a hiba, mert lefoglalja a hívót
Unbounded result setslekérdezés limit nélkülselect * lapozás nélkül, LLM válasz max token nélkül

8.2 Stabilitási minták

MintaLényegeKonkrétan
Timeoutsminden külső hívásnak legyen időkorlátjakapcsolódási és olvasási timeout külön, retry exponenciális visszalépéssel és jitterrel, legfeljebb kétszer-háromszor
Circuit breakerha a hibaarány átlép egy küszöböt, a hívások egy ideig azonnal elbuknak, majd félig nyitott állapotban próbálkozikzárt, nyitott, félig nyitott állapot. Könyvtár például opossum (Node), resilience4j (Java), Polly (.NET)
Bulkheadserőforrások elkülönítése, hogy egy rész kimerülése ne vigye el a többitkülön connection pool vagy szálkészlet a kritikus és a kevésbé kritikus hívásoknak, külön példány a riportolásnak
Steady statea rendszer emberi beavatkozás nélkül hosszú ideig futtathatónaplórotáció, régi adatok törlése vagy archiválása, cache méretkorlát
Fail fastha előre látszik, hogy a kérés el fog bukni, azonnal elutasítjukerőforrások ellenőrzése a munka elején, bemenet validálás a határon
Let it crashegy komponens inkább induljon újra tiszta állapotból (Erlang hagyomány)felügyelő újraindít, gyors indulás kell hozzá
Handshakinga szerver jelezheti, hogy nem tud több munkát fogadnihealth check, ami a valós kapacitást mutatja, HTTP 503 Retry-After fejléccel
Test harnesseshamis külső szolgáltatás, ami hibásan viselkediklassú, félig válaszoló, rossz formátumú válasz szimulálása
Decoupling middlewareüzenetsor időben elválasztja a küldőt és a fogadót
Shed loadtúlterhelésnél kérések eldobása, hogy a többit ki lehessen szolgálnirate limit, 429 válasz
Create back pressurea fogyasztó lassítja a termelőt, korlátos sorralkorlátos várakozási sor, ami tele állapotban blokkol vagy elutasít
Governoraz automatizálás sebességének korlátozásaautoscaler lépcső és felső korlát, megerősítés kérése romboló műveleteknél

Mai alkalmazás LLM hívásokra. Az LLM szolgáltató is integrációs pont, ugyanazok a szabályok érvényesek rá. Timeout, retry jitterrel a 429 és a túlterhelést jelző 5xx válaszoknál, költségkorlát (governor), max_tokens (unbounded result set ellen), tartalék modell vagy degradált válasz (circuit breaker után), és bulkhead, hogy a háttérben futó kötegelt feldolgozás ne egye meg az interaktív felhasználók kvótáját.

async function hivasTimeouttal<T>(fn: (s: AbortSignal) => Promise<T>, ms = 10_000, proba = 3): Promise<T> {
  for (let i = 0; ; i++) {
    const ac = new AbortController();
    const t = setTimeout(() => ac.abort(), ms);
    try { return await fn(ac.signal); }
    catch (e) {
      if (i >= proba - 1 || !ujraprobalhato(e)) throw e;
      await new Promise(r => setTimeout(r, 2 ** i * 500 + Math.random() * 250)); // backoff plusz jitter
    } finally { clearTimeout(t); }
  }
}

9. A Philosophy of Software Design (Ousterhout, 2. kiadás 2021)

Ousterhout a bonyolultságot három tünettel írja le. Ezek a változásfelnagyítás (egy egyszerű változás sok helyen kell), a kognitív terhelés (mennyit kell tudni egy változtatáshoz) és az ismeretlen ismeretlenek (nem derül ki, mit kell módosítani). Okai a függőségek és a homályosság (obscurity).

9.1 Fő elvek

Mély modulok. A modul értéke a funkcionalitás és a felület aránya. Mély modul egyszerű felület mögött sok funkciót rejt (a Unix fájl I/O öt hívással). Sekély modul felülete majdnem olyan bonyolult, mint a megvalósítása. Az osztályok minél kisebbre darabolása (classitis) sok sekély modult szül.

Információrejtés és szivárgás. A Parnas elv mai formája. Information leakage akkor van, ha ugyanaz a tervezési döntés (például egy fájlformátum) több modulban is megjelenik. Tipikus oka a temporal decomposition, amikor a kód a végrehajtás sorrendje szerint bomlik (olvasás, feldolgozás, írás modul), pedig a fájlformátum ismerete mindháromba kell.

Az általános célú modulok mélyebbek. A felület legyen kissé általánosabb, mint a mostani igény, a megvalósítás viszont a mostani igényt szolgálja. Ellenőrző kérdés, hogy mi a legegyszerűbb felület, ami lefedi az összes jelenlegi igényt.

A bonyolultság lefelé húzása (pull complexity downward). Jobb, ha a modul írója szenved, mint ha minden hívója. Konfigurációs paraméter helyett jó alapértelmezés kell.

Define errors out of existence. A kivételek bonyolultságot adnak. Ezért úgy tervezzük a szemantikát, hogy a hibaeset ne létezzen. Például a delete idempotens (ha nincs mit törölni, az is siker), a substring a tartományon kívüli indexeket levágja. Egyéb technikák a kivétel elfedése (exception masking), az aggregálás (sok hibát egy helyen kezelünk) és az összeomlás (just crash), ha a hiba ritka és helyreállíthatatlan.

Különböző réteg, különböző absztrakció. Ha két szomszédos réteg ugyanazt az absztrakciót kínálja, az egyik felesleges. Ennek tünete a pass through method.

Stratégiai és taktikai programozás. A taktikai programozó a feature gyors elkészülésére optimalizál, a stratégiai a rendszer szerkezetére is (a szerző a munkaidő 10 és 20 százaléka közé teszi ezt a befektetést). Tactical tornado az a fejlesztő, aki gyorsan szállít és szétszórt bonyolultságot hagy maga után. Kontroll nélküli AI generálás ennek gépi változata.

Kommentek. A komment azt írja le, ami a kódból nem derül ki (miért, milyen feltételek mellett, milyen mértékegységben). Előbb készüljön el a felület kommentje, mint a megvalósítás (comment driven design), mert ha nehéz leírni, rossz a felület.

9.2 Red flags

JelMit jelent
Shallow modulea felület nem sokkal egyszerűbb, mint a megvalósítás
Information leakageugyanaz a döntés több modulban
Temporal decompositiona szerkezet a végrehajtás sorrendjét követi, nem a rejtett tudást
Overexposurea gyakori használathoz ritka funkciókat is ismerni kell
Pass through methoda metódus csak továbbadja a paramétereit egy hasonló metódusnak
Repetitionugyanaz a kódrészlet több helyen
Special general mixtureaz általános célú kódba speciális esetek keverednek
Conjoined methodskét metódust csak együtt lehet megérteni
Comment repeats codea komment a kódot ismétli
Implementation documentation contaminates interfacea felület kommentje megvalósítási részleteket tartalmaz
Vague namea név semmit nem mond (data, info, manager, handle)
Hard to pick namenehéz nevet adni, a felelősség nem tiszta
Hard to describea dokumentáció hosszú, a modul túl sokat csinál
Nonobvious codea viselkedés nem érthető gyors olvasásra

AI asszisztált fejlesztésnél. A generált kód két jellegzetes hibája a sekély modul (minden egy apró utils függvény vagy wrapper osztály) és a repetition (a modell nem tud a meglévő segédfüggvényről, ezért újat ír). Ellenszer, hogy új függvény írása előtt az AI asszisztens keres a kódbázisban (grep a hasonló nevekre és mintákra), és a modul felületét előbb mondatokban fogalmazza meg.

10. Team Topologies, Conway törvénye, kognitív terhelés

10.1 Négy csapattípus, három interakciós mód

CsapattípusFeladat
Stream alignedegy értékfolyamért (termék, felhasználói út) felel végponttól végpontig. Ez az alapértelmezés, a többi őt szolgálja
Enablingideiglenesen segít egy stream aligned csapatnak új képesség elsajátításában
Complicated subsystemmély szakértelmet igénylő részt visz (videókódoló, számítási motor, ML modell)
Platformbelső szolgáltatásokat ad önkiszolgáló módon, hogy csökkentse a stream aligned csapatok terhét
Interakciós módMikor
Collaborationfelfedezés idején, rövid ideig, magas költséggel
X as a Servicestabil, jól definiált felületnél, alacsony koordinációval
Facilitatingenabling csapat segít, majd kivonul

10.2 Conway törvénye és az inverz manőver

Conway törvénye (1968) szerint a rendszer szerkezete a szervezet kommunikációs szerkezetét másolja. Az inverz Conway manőver ezt tudatosan használja, előbb a kívánt architektúrát tervezik meg, majd ahhoz igazítják a csapatokat és a kommunikációs csatornákat. Ha három csapat dolgozik egy rendszeren, három fő komponens lesz, akár akarják, akár nem.

10.3 Kognitív terhelés

Egy csapat (és egy ember) kognitív kapacitása korlátos, a terhelésnek három típusa van. Intrinsic (a feladat lényegi nehézsége), extraneous (a környezet okozta, például bonyolult deploy, kézi lépések, rossz eszközök), germane (a domain megértése, ez az értékes). Az extraneous terhet kell minimalizálni, hogy maradjon kapacitás a germane részre. A szoftver határait úgy húzzuk meg, hogy egy csapat egy darabot teljesen fejben tudjon tartani (team sized software).

A 2025-ös 2. kiadás a megközelítést a platform szemlélet és a gyors áramlás (fast flow) irányába finomítja, a lényeg változatlan (a 2026 októberi állapot szerint, ellenőrizendő).

Egyszemélyes fejlesztés AI asszisztenssel. Itt a csapat egy ember, a kognitív kapacitás egy emberé. Az AI asszisztens csökkenti az extraneous terhet (boilerplate, konfiguráció), de növelheti is, ha a generált szerkezet több darabból áll, mint amit egy ember átlát. Szabály, hogy a rendszer annyi deploy egységből, annyi technológiából és annyi modulból álljon, amennyit a fejlesztő fejben tud tartani. A platform csapat szerepét a menedzselt szolgáltatások töltik be (Supabase, Vercel, Cloudflare).

11. Megbízhatóság mérése, SRE és DORA

11.1 SLI, SLO, error budget

FogalomMeghatározásPélda
SLI (service level indicator)mért arány, jó események per összes eseménysikeres (nem 5xx) és 300 ms alatti válaszok aránya
SLO (service level objective)cél az SLI-re egy időablakban99,5% 28 napos gördülő ablakban
SLA (service level agreement)szerződéses vállalás következménnyelaz SLO-nál lazább
Error budget1 mínusz SLO0,5%, azaz 28 napon kb. 3 óra 22 perc

Lépések

  1. Felhasználói út kiválasztása (bejelentkezés, ajánlat megnyitása, fizetés).
  2. SLI meghatározása a felhasználó szemszögéből (rendelkezésre állás, késleltetés, helyesség, frissesség).
  3. SLO beállítása a jelenlegi teljesítmény és az igény alapján. A 100% helytelen cél.
  4. Error budget szabály írásban. Ha a büdzsé elfogyott, új funkció helyett megbízhatósági munka jön.
  5. Riasztás a büdzsé fogyási sebességére (burn rate), nem minden egyes hibára. A Workbook többablakos burn rate riasztást javasol (például 1 órás és 5 perces ablak 14,4 szeres fogyásnál).

11.2 Toil

A toil kézi, ismétlődő, automatizálható, taktikai, tartós érték nélküli munka, ami a szolgáltatás méretével lineárisan nő. Google célja, hogy az SRE munkaidő legfeljebb 50 százaléka legyen toil. Kis csapatnál a toil azonosítása egyszerű, ami harmadszor fordul elő kézzel, azt szkript vagy ütemezett feladat váltja ki.

11.3 Accelerate és DORA metrikák

MetrikaMit mérCsoport
Deployment frequencymilyen gyakran kerül élesbe változásáteresztés (throughput)
Lead time for changescommit és éles között eltelt időáteresztés
Change failure rateélesítések hány százaléka okoz hibátstabilitás
Failed deployment recovery time (korábban time to restore)mennyi idő alatt áll helyre egy hibás élesítés utánstabilitás
Rework rate (2024 óta)nem tervezett, hibajavító élesítések arányastabilitás

A 2021-es jelentés az operatív teljesítményt (reliability) ötödik dimenzióként vezette be, a 2024-es pedig a rework rate-et ötödik élesítési metrikaként. Az Accelerate kutatás fő eredménye, hogy a sebesség és a stabilitás nem egymás ellen hat, a legjobb csapatok mindkettőben jók. A 2024 és 2025 közötti DORA jelentések szerint az AI használat növeli az egyéni produktivitást, de kontroll nélkül ronthatja a szállítási stabilitást. Javulás ott jön, ahol megvan a kis változtatási csomag, az erős tesztelés és a jó belső platform, vagyis az AI felerősíti azt, ami a csapatban már megvan (a 2026 októberi állapot szerint).

Kis csapatnál AI asszisztenssel. A DORA metrikák közül a lead time és a change failure rate a hasznos. Cél a sok kicsi, gyakori, visszafordítható élesítés a ritka nagy helyett.

12. Twelve Factor App és ami azóta változott

#FaktorEredeti lényeg (2011)2026-os megjegyzés
ICodebaseegy kódbázis verziókezelve, sok deploymonorepó is elfogadott, ha a deploy egységek világosak
IIDependenciesexplicit deklarálás és izoláláslock fájl kötelező, ellátási lánc ellenőrzés (SBOM, SLSA)
IIIConfigkonfiguráció környezeti változóbana titkok titokkezelőben (Vault, Doppler, Supabase secrets), nem .env fájlban a repóban
IVBacking servicesa csatolt erőforrás cserélhető URLváltozatlan
VBuild, release, runszigorúan elválasztott fázisokimmutable artifact, konténer kép digest szerint
VIProcessesállapotmentes folyamatokserverless és edge esetén magától értetődő
VIIPort bindinga szolgáltatás saját portot exportálserverless platformnál nem releváns
VIIIConcurrencyskálázás folyamatokkala platform végzi (autoscaling)
IXDisposabilitygyors indulás, kecses leálláscold start serverlessnél újra fontos
XDev/prod parityfejlesztés és éles hasonlópreview környezet ágonként, helyi Supabase
XILogseseményfolyam a stdout-rastrukturált napló, OpenTelemetry nyomkövetés és metrika
XIIAdmin processesegyszeri feladatok ugyanabban a környezetbenmigrációk verziózva, CI-ből futtatva

Azóta hozzájött (Kevin Hoffman, Beyond the Twelve Factor App, 2016, plusz a mai gyakorlat). API first tervezés, telemetria (megfigyelhetőség mint első osztályú követelmény), hitelesítés és jogosultság minden kérésnél (zero trust), feature flag, infrastruktúra mint kód. A Heroku 2024-ben nyílt forrásúvá tette a 12 factor szöveget, hogy a közösség modernizálja. Titokkezelés és zero trust ügyében a biztonsági részleteket a kiberbiztonsági kézikönyv tárgyalja.

13. Meglévő kód megváltoztatása

13.1 Refactoring (Fowler, 2. kiadás 2018)

A refaktorálás a kód belső szerkezetének megváltoztatása a megfigyelhető viselkedés megváltoztatása nélkül, kis, biztonságos lépésekben, mindegyik után futó tesztekkel. Fowler 2. kiadása JavaScript példákkal dolgozik, és a függvényeket az osztályokkal egyenrangúan kezeli.

Két kalap szabály (Kent Beck). Egy időben vagy funkciót adunk hozzá, vagy refaktorálunk. A kettő nem keveredik egy lépésben és egy commitban.

Code smells (a 2. kiadás 24 szaga)

SzagTipikus refaktor
Mysterious NameRename Variable, Change Function Declaration
Duplicated CodeExtract Function, Slide Statements
Long FunctionExtract Function, Replace Temp with Query, Decompose Conditional
Long Parameter ListIntroduce Parameter Object, Preserve Whole Object
Global DataEncapsulate Variable
Mutable DataEncapsulate Variable, Separate Query from Modifier
Divergent ChangeSplit Phase, Extract Class (egy modul sokféle okból változik)
Shotgun SurgeryMove Function, Combine Functions into Class (egy változás sok helyen)
Feature EnvyMove Function
Data ClumpsExtract Class, Introduce Parameter Object
Primitive ObsessionReplace Primitive with Object (value object)
Repeated SwitchesReplace Conditional with Polymorphism
LoopsReplace Loop with Pipeline
Lazy ElementInline Function, Inline Class
Speculative GeneralityCollapse Hierarchy, Remove Dead Code
Temporary FieldExtract Class, Introduce Special Case
Message ChainsHide Delegate
Middle ManRemove Middle Man
Insider TradingMove Function, Hide Delegate
Large ClassExtract Class, Extract Superclass
Alternative Classes with Different InterfacesChange Function Declaration, Move Function
Data ClassEncapsulate Record, Move Function
Refused BequestPush Down Method, Replace Superclass with Delegate
CommentsExtract Function, Introduce Assertion

AI asszisztált fejlesztésnél. A refaktorálási kérés egy szagot, egy refaktort és egy commitot jelent. Ha egy kérés funkcióváltozást és refaktort keverne, az AI asszisztens ezt jelzi, és kettébontja.

13.2 Legacy kód (Feathers 2004)

Feathers definíciója szerint legacy kód az, aminek nincs tesztje. A dilemma, hogy a változtatáshoz teszt kellene, a teszthez pedig változtatás (a függőségek miatt).

Seam (varrat). Olyan hely, ahol a viselkedés a kód szerkesztése nélkül megváltoztatható. Minden seamnek van engedélyező pontja (enabling point), ahol eldől, melyik viselkedés fut.

Seam típusEngedélyező pontMai megfelelő
Preprocessing seammakró, fordítás előtti feldolgozásbuild flag
Link seammelyik könyvtár linkelődikmodul alias, vi.mock, jest.mock
Object seammelyik objektumot kapja a kódfüggőség injektálás, paraméterként átadott kliens

A legacy kód változtatási algoritmusa

  1. Változási pontok azonosítása.
  2. Tesztpontok megkeresése.
  3. Függőségek megtörése (seam bevezetése).
  4. Tesztek írása.
  5. Változtatás és refaktorálás.

Characterization test. Olyan teszt, ami a jelenlegi viselkedést rögzíti, nem a helyeset. Írunk egy tesztet szándékosan rossz elvárással, a hibaüzenetből kiolvassuk a tényleges eredményt, és azt írjuk be elvárásnak. Mai változata a snapshot vagy golden master teszt, és az approval testing.

Technikák új kódhoz régi környezetben. Sprout method vagy sprout class (az új logika új, tesztelt függvénybe kerül, a régi csak meghívja), wrap method vagy wrap class (a régi köré tesztelt burok kerül).

AI asszisztált fejlesztésnél. Ismeretlen kód módosítása előtt az AI asszisztens először characterization teszteket ír a módosítandó függvényekre, és csak utána változtat. Ez kiszűri, ha a generált változtatás csendben más viselkedést is módosít.

13.3 Strangler Fig (Fowler 2004)

Az új rendszer fokozatosan nő a régi köré, és funkciónként veszi át a forgalmat, amíg a régi kikapcsolható.

Lépések

  1. Homlokzat (proxy, API gateway, router) a régi rendszer elé, kezdetben mindent átenged.
  2. Egy szelet kiválasztása (kis, jól körülhatárolt, értékes funkció).
  3. A szelet megírása az új rendszerben.
  4. A homlokzat az adott útvonalat az újra irányítja (feature flaggel, fokozatosan).
  5. Párhuzamos futtatás (parallel run), ha a helyesség kritikus. Mindkettő fut, az eredményeket összevetjük, és a régi a mérvadó.
  6. A régi kód törlése az adott szeletre.
  7. Ismétlés.

Kapcsolódó minták Newmantól a branch by abstraction (a kódon belül absztrakció mögé kerül a régi és az új implementáció), a decorating collaborator és a change data capture (az adatváltozások folyama a régi adatbázisból).

13.4 Tidy First? (Kent Beck 2023)

Alapgondolat. A szerkezeti változtatást (tidying) elválasztjuk a viselkedési változtatástól, külön commitban, ideálisan külön PR-ban. Minden alkalommal felmerül, hogy előbb jöjjön a rendrakás, utána, később vagy soha. A válasz gazdasági. Előbb akkor érdemes rendet rakni, ha az olcsóbbá teszi a következő változtatást, és maga is olcsó.

Tidyingek (kis, biztonságos lépések)

TidyingMit csinál
Guard clauseskorai visszatérés a mély beágyazás helyett
Dead codehasználaton kívüli kód törlése
Normalize symmetriesugyanaz a dolog mindenhol ugyanúgy legyen megírva
New interface, old implementationa kívánt felület bevezetése, ami a régit hívja
Reading ordera fájl sorrendje az olvasás sorrendje
Cohesion orderaz együtt változó elemek egymás mellé kerülnek
Move declaration and initialization togetherdeklaráció és kezdőérték egy helyre kerül
Explaining variables, explaining constantsmagyarázó nevű változó vagy konstans egy kifejezés helyett
Explicit parametersrejtett bemenet (globális, környezet) helyett paraméter
Chunk statementsüres sor a logikai blokkok között
Extract helpersegédfüggvény kiemelése
One piletúldarabolt kód visszaolvasztása, hogy átlátható legyen, majd újradarabolás
Explaining comments, delete redundant commentsmagyarázó komment ott, ahol kell, a felesleges törlése

Elméleti háttér. A szoftver költsége lényegében a változtatás költsége, ami a csatolás költsége (Constantine egyenértékűsége). Rendrakással opció születik a jövőbeli változtatásra. Az időérték elve szerint a ma megszerzett érték többet ér, mint a holnapi, ezért a rendrakás nem lehet öncél.

AI asszisztált fejlesztésnél. A funkcióváltozás előtt egy külön commitban készülnek el a szükséges tidyingek (például guard clause, explaining variable), lefutnak a tesztek, és csak utána jön a viselkedési változás. Így a diff olvasható marad.

14. Tesztelés, TDD, piramis és trófea

14.1 TDD (Beck 2002)

A ciklus

  1. Red. Egy kicsi, bukó teszt a következő viselkedésre.
  2. Green. A legkisebb kód, amitől átmegy (akár hamisítva).
  3. Refactor. A duplikáció és a rossz szerkezet eltüntetése, zöld tesztekkel.

Teszt lista. A munka elején felírjuk a teszteseteket, amelyek eszünkbe jutnak, és egyesével haladunk. Beck 2023-ban a Canon TDD írásában megerősítette, hogy a lista, a lépésenként egy teszt és a refaktorálás a lényeg, nem a teszt előbb írásának dogmája.

Mikor éri meg. Üzleti szabályok, számítások, parserek, állapotgépek esetén. UI elrendezésnél és feltáró prototípusnál kevésbé.

AI asszisztált fejlesztésnél. A TDD kiváló kontroll a generált kód fölött. Előbb a kódgeneráló modell írja meg a teszteket a specifikációból, ezeket a fejlesztő jóváhagyja (ez olcsóbb, mint a kódot átnézni), majd a modell addig implementál, amíg zöld nem lesz. Közben a teszteket nem módosíthatja azért, hogy átmenjenek.

14.2 Testing pyramid és testing trophy

ModellSzerzőAlakjaHangsúly
Test pyramidMike Cohn 2009, Fowler és Ham Vocke 2018 (Practical Test Pyramid)sok unit, kevesebb service vagy integrációs, kevés UI tesztgyors, olcsó, izolált tesztek a bázisban
Testing trophyKent C. Dodds 2018statikus elemzés alul, kevés unit, sok integrációs, kevés e2ea felhasználói viselkedéshez közeli tesztek adják a legtöbb bizalmat
Testing honeycombSpotify 2018kevés implementációs részlet teszt, sok integrációs, kevés integráltmicroservices környezet

Választás. Domain modellnél (sok szabály) piramis. Webalkalmazásnál, ahol a logika vékony és főleg komponensek, API és adatbázis együttműködéséből áll, trófea. A Khononov féle hozzárendelés (5.3 pont) jó kiindulás.

Mai trófea egy TypeScript projektben

Statikus:   TypeScript strict, ESLint, dependency-cruiser  (mindig, minden commitnál)
Unit:       Vitest a tiszta domain függvényekre            (ahol szabály van)
Integráció: Vitest plus helyi Supabase vagy Testcontainers (API végpontok, RLS policyk)
E2E:        Playwright 3-10 kritikus felhasználói útra     (bejelentkezés, fizetés)

Tipikus hiba. Mock mindenre, ami a tesztet a megvalósításhoz köti. Refaktornál minden teszt eltörik, a valódi hibát viszont egyik sem fogja meg. Másik gyakori hiba, hogy az AI olyan tesztet ír, ami a saját implementációját ismétli meg elvárásként, ezért mindig zöld.

15. Monolit vagy microservices, moduláris monolit

15.1 Newman döntési szempontjai

Newman szerint a microservices eszköz, nem cél és nem alapértelmezés. Akkor éri meg, ha az alábbi célok valamelyike fontos, és egyszerűbb eszközzel nem érhető el.

Microservices ellen szól, ha új a domain és még nem tiszták a határok (a rossz határt elosztott rendszerben nagyon drága javítani), kicsi a csapat, nincs automatizált deploy és megfigyelhetőség, vagy a fő cél a sebesség egy új terméknél. Newman és Fowler (MonolithFirst, 2015) egyaránt monolittal kezdést javasol új rendszernél.

Az elosztott rendszer költségei. Hálózati késleltetés és hiba (az elosztott számítástechnika tévhitei, Deutsch), végső konzisztencia, elosztott nyomkövetés, verziózás, szerződéstesztek, több deploy pipeline, nehezebb lokális fejlesztés.

Monolith to Microservices migrációs lépések

  1. A cél megfogalmazása (miért akarunk szétbontani, mit mérünk).
  2. Domain modell és határok (event storming, context map).
  3. Az első szolgáltatás kiválasztása. Alacsony bonyolultság, magas érték, kevés adatfüggőség.
  4. Kódszétválasztás (strangler fig, branch by abstraction).
  5. Adatszétválasztás (először séma, aztán adatbázis, a 3.2 pont szerint), olyan mintákkal, mint a database view, a database wrapping service és a change data capture.
  6. Mérés, majd a következő szelet.

15.2 A moduláris monolit kialakítása

Szabályok

  1. Domain particionálás. A felső szintű mappák bounded contextek vagy subdomainek (ajanlat, szamlazas, crm), nem technikai rétegek (controllers, services, models).
  2. Nyilvános felület modulonként. Egy index.ts vagy api csomag, minden más belső. Fitness function ellenőrzi (4.2 pont).
  3. Adattulajdonlás. Minden tábla egy modulhoz tartozik, más modul nem írja, és lehetőleg közvetlenül nem is olvassa, hanem a tulajdonos modul felületén keresztül éri el. Postgresben séma per modul.
  4. Kommunikáció a modulok között. Szinkron függvényhívás a nyilvános felületen, vagy belső domain event (in process event bus, outbox táblával, ha megbízható kézbesítés kell).
  5. Nincs ciklikus függőség a modulok között.
  6. Közös kód minimális. A shared csak stabil, domain független típusokat tartalmaz. Ami üzleti logika, az egy modulé.
  7. Egy deploy, egy adatbázis. A modularitás logikai, a fizikai szétválasztás opció marad.

Eszközök. Spring Modulith (Java), Packwerk (Ruby, a Shopify, amely a moduláris monolitot nagy léptékben is megmutatta), Nx vagy Turborepo modulhatárokkal (TypeScript), import-linter (Python), .NET esetén projektek modulonként és NetArchTest.

Mikor érdemes továbblépni. Ha egy modulnak quantum szinten eltérő jellemző kell (elasticity, eltérő biztonsági zóna), vagy egy modult külön csapat visz. Ilyenkor az a modul kiemelhető egy service based architektúra szolgáltatásává, a határ már megvan.

16. A gyakorlatban

A cél, hogy a generálás sebessége ne rontsa a szerkezetet. Az alábbi szabályok a tervezés, az írás és az asztali ellenőrzés hagyományos munkarendjét egészítik ki architektúra szinten, és ugyanúgy érvényesek kézzel írt és AI asszisztenssel generált kódra.

16.1 Öt perces architektúra kártya új projekt előtt

Új projekt vagy új nagyobb modul előtt a csapat kitölti ezt a kártyát, és a döntéshozóval együtt átnézi. A kártya a repó gyökerébe kerül (ARCHITECTURE.md), vagy az AI asszisztens projektszintű instrukciós fájljának elejére.

# Architektúra kártya. <projekt>, <dátum>

**Egy bekezdés.** Mit csinál a rendszer, kinek, milyen fő úton.

**Top 3 jellemző** (mérhető céllal)
1. ...
2. ...
3. ...
Szándékosan nem optimalizált: ...

**Subdomainek**
| Terület | Típus (core, supporting, generic) | Megoldás (saját kód, kész szolgáltatás) |

**Stílus és quantumok.** Például moduláris monolit, 1 quantum, Next.js plus Supabase.
Miért nem más: ...

**Modulok és adattulajdonlás**
| Modul | Felelősség egy mondatban | Saját táblák vagy séma |

**Bizalmi határok és integrációs pontok** (mindegyikhez timeout, ACL adapter)
| Külső rendszer | Irány | Adapter fájl | Timeout és retry |

**Fitness functionök a CI-ben**
- modulhatár (dependency-cruiser), RLS minden táblán, ...

**Nyitott kérdések (hot spotok).** Ezekre nem generálunk kódot, amíg el nem dőlnek.

**ADR-ek.** docs/adr/0001-..., 0002-...

16.2 A generált kód tipikus architekturális hibái és felismerésük

HibaFelismerésJavítás
Entity trap, táblák köré szervezett CRUD service-ekUserService, OrderService nevek, a viselkedés a route handlerekbendomain particionálás, use case függvények
Szivárgó külső modellStripe, Supabase vagy LLM SDK típusok a domain kódbanACL adapter, saját típusok (dependency-cruiser szabállyal)
Szétszórt jogosultságif (user.role === ...) sok fájlban, vagy csak a frontendenegy helyen (RLS, middleware, policy modul), szerver oldalon
Hiányzó timeout és retryfetch vagy SDK hívás signal és időkorlát nélküla 8.2 pont mintái egy közös wrapperben
Unbounded result setlekérdezés limit nélkül, LLM hívás max_tokens nélküllapozás, korlátok
Duplikált segédfüggvényekhasonló nevű függvények (formatDate, fmtDate, dateToString)keresés írás előtt, egy helyre vonás
Sekély wrapperek és spekulatív általánosításinterfész egyetlen implementációval, factory egy termékkel, nem használt konfigurációs opciókinline, YAGNI, Ousterhout mély modulja
Rejtett ciklikus függőségkét modul kölcsönösen importáldependency-cruiser no-circular
Disztribuált monolittöbb edge function vagy szolgáltatás egy adatbázison, szinkron láncban hívják egymástegy deploy egység, vagy valódi szétválasztás adattal együtt
Kettős írásadatbázis írás, utána külön esemény vagy email küldés tranzakción kívüloutbox tábla, vagy idempotens újrapróbálás
Keveredő szerkezeti és viselkedési változásegy diffben átnevezés, mozgatás és új funkcióTidy First, külön commitok
Teszt, ami a megvalósítást tükrözia teszt elvárása ugyanazzal a képlettel számol, mint a kódkonkrét példaértékek, specifikációból írt teszt
Konfiguráció és titok a kódbanAPI kulcs vagy URL literálkéntkörnyezeti változó, titokkezelő
Architektúra sodródás munkamenetek közöttminden új munkamenet más mintát követ (egyszer server action, egyszer API route)ARCHITECTURE.md, fitness function és ADR, amelyeket az AI asszisztens minden munkamenet elején beolvas

16.3 Mikor kell ADR

ADR vázlat készül, ha az alábbiak valamelyike igaz.

Keretrendszeren belüli szokásos döntésre, könnyen visszafordítható implementációs részletre és ízlésbeli kérdésre nem kell ADR. Ha az AI asszisztens dolgozik a kódon, ezekben a helyzetekben ő is jelzi az ADR igényét, és megírja a vázlatot, amelyet a fejlesztő hagy jóvá.

16.4 Munkaszabályok

  1. Munka előtt olvasunk. A fejlesztő és az AI asszisztens is elolvassa az ARCHITECTURE.md-t, a projektszintű instrukciós fájlt és a releváns ADR-eket, és a meglévő mintát követi. Az eltérést előbb jelezni és indokolni kell.
  2. A legegyszerűbb stílus az alapértelmezés. Moduláris monolit egy adatbázissal. Elosztott elem (üzenetsor, külön szolgáltatás, külön adatbázis) csak megnevezett jellemző és ADR alapján kerül be.
  3. Minden javaslat költséggel. Az első törvény szerint minden javaslathoz tartozik egy mondat arról, mit ad fel.
  4. Domain particionálás és közös nyelv. A mappák és a nevek a fogalomtárat követik, nem a technikai szerepet.
  5. Külső világ adapter mögött. Minden külső API, SDK és LLM hívás egy fájlban él, timeouttal, retryjal, saját típusokkal.
  6. Kis lépések, külön szerkezet és viselkedés. Tidying külön commitban, refaktor egy szag szerint, funkció tesztekkel.
  7. Ismeretlen kódnál a characterization teszt jön előbb.
  8. A szabályokból fitness function lesz. Amit kétszer kell kézzel ellenőrizni, az CI szabállyá válik (modulhatár, ciklusmentesség, RLS, bundle méret).
  9. Stabilitási minimum minden integrációs pontra. Timeout, korlátozott retry jitterrel, eredményhalmaz korlát, költségkorlát LLM hívásnál, idempotens újrapróbálás.
  10. Kognitív keret. A rendszer maradjon akkora, amekkorát egy ember átlát. Ha egy változtatás után több a deploy egység, a technológia vagy a modul, mint előtte, ezt kimondjuk, és megvizsgáljuk, megéri-e.
  11. Mérés. Éles rendszernél legalább egy SLO tartozik a legfontosabb felhasználói útra, a hibák után pedig rövid, hibáztatás nélküli visszatekintés készül, amiből fitness function vagy teszt születik.
  12. Mielőtt késznek mondjuk. A saját diffet végigvetjük a 16.2 pont táblázatán, és amit nem ellenőriztünk, azt kimondjuk.

16.5 Gyors döntési táblázat

HelyzetJavasolt kiindulás
Belső eszköz, egy felhasználói kör, kevés szabálymoduláris monolit, transaction script, vertical slice, trófea tesztelés
Ügyféladatot kezelő SaaS, több bérlőmoduláris monolit, RLS, auditálhatóság a top 3-ban, ADR a bérlőelválasztásról
Bonyolult árazás, szabálymotor, core domaindomain model aggregátumokkal, ports and adapters a core modulban, TDD
LLM feldolgozó lánc (dokumentum betöltés, darabolás, embedding)pipeline stílus, idempotens lépések, timeout és költségkorlát minden LLM hívásnál
Bővíthető termék ügyfélenkénti testreszabássalmicrokernel, plugin szerződés, regiszter
Legacy rendszer cseréjestrangler fig, characterization tesztek, ACL a régi modell felé
Hirtelen, extrém terhelési csúcs (jegyértékesítés)előbb mérés és cache, sor alapú backpressure, space based csak végső esetben
Több csapat, eltérő skálázási igény, érett domainservice based, majd indokolt esetben microservices, quantumonként saját adattal

Források

A kiadások a 2026 októberi állapotot tükrözik.

MűSzerzőKiadás
Fundamentals of Software ArchitectureMark Richards, Neal Ford2. kiadás, 2025 március
Software Architecture: The Hard PartsFord, Richards, Sadalage, Dehghani2021
Building Evolutionary ArchitecturesFord, Parsons, Kua, Sadalage2. kiadás, 2022
Software Architecture in PracticeBass, Clements, Kazman4. kiadás, 2021
Domain Driven DesignEric Evans2003
Implementing Domain Driven Design, Domain Driven Design DistilledVaughn Vernon2013, 2016
Learning Domain Driven DesignVlad Khononov2021
Introducing EventStormingAlberto Brandolini2013 óta folyamatosan bővülő elektronikus könyv
Hexagonal Architecture (Ports and Adapters)Alistair Cockburn2005
Onion ArchitectureJeffrey Palermo2008
Clean ArchitectureRobert C. Martinblog 2012, könyv 2017
C4 modelSimon Brown2011 óta, c4model.com
arc42Gernot Starke, Peter Hruschka2005 óta, 8.x sablon
Documenting Architecture DecisionsMichael Nygardblogposzt, 2011
MADRMarkdown Architectural Decision Records4.0, 2024
Release It!Michael Nygard2. kiadás, 2018
A Philosophy of Software DesignJohn Ousterhout2. kiadás, 2021
Team TopologiesMatthew Skelton, Manuel Pais2019, a 2. kiadás 2025 (ellenőrizendő)
Site Reliability Engineering, The Site Reliability WorkbookGoogle2016, 2018
AccelerateForsgren, Humble, Kim2018, plusz az éves DORA jelentések
The Twelve Factor AppAdam Wiggins (Heroku)2011, nyílt forrású 2024 óta
Beyond the Twelve Factor AppKevin Hoffman2016
RefactoringMartin Fowler2. kiadás, 2018
Working Effectively with Legacy CodeMichael Feathers2004
Tidy First?Kent Beck2023
Test Driven Development: By ExampleKent Beck2002
Building Microservices, Monolith to MicroservicesSam Newman2. kiadás 2021, illetve 2019

Állapot 2026 októberében. A szöveg szakmai összefoglaló, a hivatkozott művek aktuális kiadását érdemes a kiadónál ellenőrizni.