/ janturon.cz / Od kodéra k analytikovi / Architektonické vzory

Architektonické vzory

Nutnou podmínkou trvale udržitelné aplikace je zamezení nárůstu složitosti při jejích úpravách a rozšiřování. Nárůst složitosti má na aplikaci stejný účinek, jako stárnutí na organismus: při každém pohybu ho něco bolí a nefunguje, až se dostane do stavu, kdy není schopen pokračovat a umírá. Dobrý analytik umí navrhovat nesmrtelné aplikace, zdraví je však nutno udržovat na všech úrovních:

Testovací úroveň
popis problému: nárůst kódu zvyšuje pravděpodobnost přehlédnutí chyby
vyřešení problému: jednotkové (unit) testy
Implementační úroveň
popis problému: nárůst kódu vede k zašmodrchanosti (vnořené cykly, složité podmínky - špagety)
vyřešení problému: abstrakce a rozděl a panuj
Návrhová úroveň
popis problému: rostoucí množství funkcí a objektů volajících se bez jakýchkoliv pravidel (big ball of mud)
vyřešení problému: návrhové vzory
Analytická úroveň
popis problému: jednoduchý požadavek na větší systém vede ke obtížněji realizovatelnému řešení
vyřešení problému: architektura aplikace

Každé pravidlo, kterým se systém řídí, by mělo zvyšovat jeho přehlednost. Každé pravidlo ale systém omezuje a vyžaduje jeho znalost. Dobré pravidlo by tedy mělo výrazně zvyšovat přehlednost, být intuitivní a co nejméně omezující. Dobrý systém umožňuje jednoduchou úpravu jednoduše realizovat. Každý systém, v němž narůstá složitost, je odsouzený k zániku ze stejných důvodů, jaké byly popsány při vysvětlení rozděl a panuj.

Nedaří se nalézt univerzální řešení na všechny problémy. Touha po větší univerzálnosti, než vyžaduje doména aplikace, vede k nadbytečné složitosti - je to antivzor.

Jedním z osvědčených vzorů je přibližně rozdělit aplikaci na následující části:

Datové objekty

DTO (Data Transfer Object) jsou objekty tříd pro manipulaci s daty odstiňující klienta od logiky práce s úložištěm. Pokud je úložiště například databáze, nemusí se klient starat o připojení, práci s dotazy a uvolňováním zdrojů: prostě zavolá metodu getStudents(), která mu vrátí pole studentů.

// uses link from MySQL C API connector vector<string>* getStudents() { mysql_query(link, "SELECT name FROM students"); response = mysql_store_result(link); int rows = mysql_num_fields(response); vector* result = new vector(); while(row=mysql_fetch_row(response)) { result->push_back(row[0]); } mysql_free_result(response); return result; }

Zásada Information Expert radí, abychom do těchto tříd zapsali i obchodní logiku aplikace. Pokud by to byl systém vyplácení stipendií, patřily by sem například dotazy getAwardedStudents(), registerStudent(), unregisterStudent(), z nichž některé by mohly vyžadovat více podmíněných dotazů. Pokud je v DTO takto zapsaná i obchodní logika, nazývají se DAO (Data Access Objects), souhrnně pak DTO + DAO = DO (Data Objects).

O tom, jak se části systému mají vzájemně volat, se vedou teoretické spory. Dobrý systém by měl být do těchto částí rozdělen přehledně a vyváženě. Pokud je nějaká část triviální, je systém navržen nevhodně. Mezi uznávaná řešení patří:

n-Tier vícevrstvá architektura

Prezentační vrstva integruje obsluhu, která volá metody aplikační (obchodní) vrstvy, která manipuluje s datovou vrstvou.

3-tier

MVC model-view-controller

Obsluha zpracovává příkazy uživatele a upravuje (volá metody) pohledu a modelu. Model při změně dat volá metody pohledu, pohled získává data voláním metod modelu.

mvc

Anemický doménový model

Je procedurální implementace MVC: model je zde redukován na databázi (a případné triviální objekty), obchodní logika je přesunuta do obsluhy. To je porušení GRASP zásady Information expert: obchodní logika a data spolu úzce souvisí, a jsou oddělena do různých částí systému, což vynucuje v obsluze tvorbu metod, které se chovají jako procedury (nepracují se stavem objektu, stav dostávají jako parametry). To má za následek složitou obsluhu a triviální kód modelu. Proto je anemický doménový model považován za antivzor.

anemic