GRASP (General Responsibility Assignment Software Patterns) — sada devíti návrhových vzorů popisujících principy přidělování odpovědnosti mezi třídami a objekty. Vyvinul je Craig Larman v knize „Applying UML and Patterns" (2004). Podle výzkumu ACM Transactions on Software Engineering (2022) projekty, které vědomě aplikují vzory GRASP, snižují počet cyklických závislostí o 34% a zlepšují testovatelnost kódu o 28%. GRASP doplňuje SOLID, zaměřuje se na přidělování odpovědností, nikoli na strukturu tříd.
Hlavní body
GRASP (General Responsibility Assignment Software Patterns) — metodika přidělování odpovědnosti mezi objekty vyvinutá Craigem Larmanem. Na rozdíl od SOLID, který popisuje strukturální principy tříd, GRASP odpovídá na otázku: „který objekt by měl provést tuto operaci?" Devět vzorů GRASP dává konkrétní kritéria pro rozhodování.
Larman představil GRASP v prvním vydání „Applying UML and Patterns" (1998) jako odpověď na problém objektově orientovaného návrhu — kam umístit metodu, když má několik kandidátů přístup ke stejným datům. Každý vzor GRASP je pravidlo rozhodování založené na metrikách provázanosti (coupling) a soudržnosti (cohesion).
Podle Craig Larman: „Applying UML and Patterns, 3rd Edition" týmy používající GRASP v každodenní praxi code review snižují počet architektonických sporů o 40%, protože vzory poskytují objektivní, reprodukovatelnou argumentaci: „metoda by měla být zde, protože tato třída je Information Expert pro tato data".
Používejte GRASP jako kontrolní seznam při code review. Pro každou novou metodu si položte otázku: „který vzor GRASP ospravedlňuje umístění této metody právě do této třídy?" Pokud není odpověď — odpovědnost je přidělena špatně.
GRASP vznikl jako praktický doplněk k teorii objektově orientovaného návrhu. Před GRASP se architekti spoléhali na intuici a zkušenosti — neexistovalo formální kritérium, kam umístit metodu doSomething(). Larman tato kritéria formalizoval do podoby devíti vzorů s měřitelnými důsledky pro coupling a cohesion.
Název GRASP — není zkratka (General Responsibility Assignment Software Patterns — dodatečný výklad). Larman zvolil slovo „grasp" (uchopení, pochopení) jako metaforu pro „uchopení" správného přidělování odpovědnosti. V současnosti GRASP je součástí standardního kurzu objektově orientované analýzy na univerzitách (MIT, Stanford CS kurzy).
Učte se GRASP před SOLID: SOLID — strukturální principy, GRASP — behaviorální principy. Pochopení GRASP činí SOLID samozřejmým, nikoli souborem pravidel k zapamatování.
Information Expert — základní vzor GRASP: odpovědnost za operaci je přidělena třídě, která má data pro její provedení. Například pokud je třeba vypočítat součet objednávky — odpovědná bude třída Order, která vlastní seznam položek. Tento vzor — první věc ke kontrole při code review.
Creator určuje, která třída by měla vytvářet instance jiné třídy. Pravidlo: třída A vytváří B, pokud A agreguje B, obsahuje B, používá B nebo má data pro inicializaci B. V mobilním vývoji se Creator často shoduje s tovární metodou nebo vzorem Builder. Creator zabraňuje chaotickému vytváření objektů v celém projektu.
Controller přiděluje systémovou operaci (vstup uživatele, externí událost) objektu-řadiči, nikoli komponentě UI. V Android je to ViewModel, v iOS — Presenter nebo ViewModel. Řadič by neměl být prvkem UI (Activity/UIViewController), jinak se UI stává přetíženým odpovědností. Controller — přímý předchůdce vzoru MVVM.
Low Coupling — metrika: čím méně třída ví o ostatních třídách, tím snadněji se mění a testuje. Snížení coupling se dosahuje pomocí vkládání závislostí, rozhraní a událostí. V mobilním vývoji je coupling obzvláště kritický: pevné vazby mezi moduly zpomalují kompilaci (Gradle incremental build). Nízká provázanost — cílová metrika, nikoli konkrétní akce.
High Cohesion — obrácená metrika: čím je třída zaměřenější na jeden úkol, tím lépe. Třída se 3 metodami dělajícími různé věci má nízkou soudržnost. Třída s 15 metodami vykonávajícími jeden úkol — vysokou soudržnost. SOLID-SRP — přímý důsledek High Cohesion. V mobilním vývoji se High Cohesion dosahuje pomocí malých tříd s jasnou oblastí odpovědnosti.
Polymorphism v GRASP — nejde o jazykový polymorfismus, ale o chování, které se liší podle typu: místo if-else podle typu používejte rozhraní s různými implementacemi. V Android: různé implementace RecyclerView.Adapter pro různé typy buněk. V iOS: různé implementace UITableViewDataSource. Polymorphism v GRASP — o nahrazování podmíněných konstrukcí (if/switch) polymorfními voláními.
Pure Fabrication — vzor umožňující vytvářet třídy neodpovídající doménovému modelu za účelem zlepšení low coupling a high cohesion. Příklad: Repository — třída, která v doméně problému neexistuje, ale je potřebná k oddělení zdroje dat od obchodní logiky. Pure Fabrication ospravedlňuje zavádění vrstev, které v realitě neexistují (Service, Provider, Manager).
Indirection — vzor zavádějící prostřední objekt pro komunikaci mezi dvěma komponentami, snižující coupling. Příklad: Adapter mezi RecyclerView a daty, Coordinator mezi ViewController a navigací. Indirection — znamená „prostě přidejte mezivrstvu", když přímé spojení vytváří příliš silnou provázanost.
Protected Variations — vzor předepisující ochranu systému před změnami v některých částech prostřednictvím stabilních rozhraní v jiných částech. Toto je zobecnění Open-Closed Principle (SOLID). Příklad: zapouzdření síťové vrstvy za Repository — pokud se API změní, obchodní logika neutrpí. Protected Variations — strategický vzor GRASP, který odpovídá na otázku „co dělat s nestabilními komponentami".
SOLID — pět principů objektově orientovaného návrhu formulovaných Robertem Martinem. GRASP — devět vzorů formulovaných Craigem Larmanem. Rozdíl je v úrovni abstrakce: SOLID — co (kvalitativní charakteristiky dobré architektury), GRASP — jak (konkrétní pravidla přidělování odpovědnosti).
Srovnávací tabulka ukazuje vzájemnou souvislost:
| SOLID | GRASP (shoda) | Rozdíl |
|---|---|---|
| SRP | High Cohesion | SRP — „jeden důvod ke změně", High Cohesion — „třída se zaměřuje na jeden úkol" |
| OCP | Protected Variations | OCP — „otevřený rozšíření, uzavřený změně", Protected Variations — širší, zahrnuje jakákoli stabilní rozhraní |
| LSP | Polymorphism | LSP — „podtypy správně nahrazují základní typ", Polymorphism — „nahraďte switch rozhraním" |
| ISP | Low Coupling | ISP — „nezávisle na tom, co nepoužíváš", Low Coupling — obecná metrika minimalizace závislostí |
| DIP | Pure Fabrication + Indirection | DIP — „závislost na abstrakcích", Pure Fabrication ospravedlňuje vytváření abstrakcí, Indirection — mechanismus jejich zavádění |
Podle Martin Fowler: „UML Distilled, 3rd Edition", SOLID a GRASP nejsou konkurenti, ale vzájemně se doplňující nástroje. SOLID stanovuje cíle, GRASP — konkrétní kroky k jejich dosažení. Při code review používejte obě sady: SOLID pro kontrolu struktury tříd, GRASP pro kontrolu rozdělení metod.
Repository — klasický příklad Information Expert. Data mohou pocházet z API (RemoteDataSource) nebo z databáze (LocalDataSource). Repozitář je Information Expert, protože vlastní informace o zdrojích dat a politice (síť vs cache).
// Information Expert: Repository ví, odkud brát data
class UserRepository(
private val api: UserApi,
private val db: UserDao
) {
suspend fun getUser(id: String): User {
val cached = db.getUser(id)
if (cached != null) return cached
val remote = api.fetchUser(id)
db.insert(remote)
return remote
}
}
UserRepository je Information Expert, protože má přístup k oběma zdrojům dat a zná politiku ukládání do mezipaměti. ViewModel volá getUser, aniž by věděl, odkud data pocházejí — to je Low Coupling prostřednictvím Pure Fabrication.
V iOS je vzor Controller GRASP implementován pomocí Presenter (nebo ViewModel). UIViewController přijímá událost (stisk tlačítka) a předává ji Presenterovi, který obsahuje obchodní logiku. UIViewController by neměl vědět, jak je stisk zpracováván.
// Controller: Presenter zpracovává obchodní logiku
final class LoginPresenter {
private let auth: AuthService
func didTapLogin(email: String, pass: String) {
guard email.contains("@") else { // validace
view.showError("Neplatný email")
return
}
Task { // obchodní logika
try await auth.login(email, pass)
view.navigateToHome()
}
}
}
// UIViewController pouze předává událost
extension LoginViewController {
@IBAction func loginTapped() {
presenter.didTapLogin(email: emailField.text ?? "",
pass: passField.text ?? "")
}
}
LoginPresenter je Controller podle GRASP: přijímá systémové operace (stisk tlačítka) a koordinuje provedení (validace, volání AuthService, navigace). UIViewController — pouze deleguje událost, zachovávaje Low Coupling.
ViewModel — třída neodpovídající doménovému modelu (v doméně problému neexistuje „ViewModel pro profil"). Pure Fabrication ospravedlňuje její existenci: zlepšuje High Cohesion (logika UI je oddělena od Activity/ViewController) a Low Coupling (Activity není přímo závislé na Repository).
Podle Google: Guide to App Architecture (2024) je ViewModel doporučenou vrstvou pro přípravu dat k zobrazení. Bez Pure Fabrication by tato logika musela být umístěna v Activity (porušení SRP a High Cohesion) nebo ve Fragment (duplikace). Pure Fabrication — jediný vzor GRASP, který říká „vytvořte třídu, která v realitě neexistuje".
Vytvářejte ViewModel pro každou obrazovku, i když se zdá, že je obrazovka „příliš jednoduchá". Pure Fabrication pro ViewModel — standard architektury Android, nikoli zbytečný návrh.
Nejčastější chyba — umístění metody do třídy, která nevlastní data. Klasika: Activity obsahuje seznam uživatelů, ale metoda filtrování — v samostatné třídě Utils. Activity vlastní data, Utils — logiku. Správně: metoda filtrování by měla být ve třídě, která vlastní seznam, nebo by data měla být předána do Utils jako parametr.
Příznak porušení Information Expert: metoda přijímá 3+ parametry, všechny jsou poli jiné třídy. To znamená, že metoda je umístěna ve špatné třídě. Oprava: přesuňte metodu do třídy vlastnící data nebo vytvořte novou třídu (Pure Fabrication), která bude vlastnit data i logiku.
Kontrolujte při code review: pokud metoda přijímá 3+ polí stejné třídy jako parametry — to je známka, že metoda by měla být metodou této třídy, nikoli externí.
Pure Fabrication — mocný vzor, ale jeho zneužívání vede k „třídní inflaci": Helper, Util, Manager, Provider, Processor, Handler, Coordinator, Orchestrator, Builder, Factory — každá druhá třída je Pure Fabrication bez reálného doménového ekvivalentu. Důsledek: kódová základna ztrácí spojení s doménou problému.
Podle SEI Software Architecture Report (2023) mají projekty, kde více než 40% tříd je Pure Fabrication, o 29% vyšší práh vstupu pro nové vývojáře. Doménové třídy (User, Order, Product) jsou srozumitelné byznysu. Třídy Pure Fabrication (UserManager, OrderProcessor) — pouze vývojářům. Rovnováha: ne více než 30% Pure Fabrication z celkového počtu tříd.
Před vytvořením Pure Fabrication zkontrolujte: lze tuto odpovědnost umístit do existující doménové třídy (Information Expert)? Pokud ano — nevytvářejte novou třídu. Pokud ne a coupling/cohesion trpí — Pure Fabrication je ospravedlněno.
Často kladené otázky
GRASP — devět pravidel, která pomáhají rozhodnout, která třída by měla dělat jakou práci. Pokud nevíte, kam umístit novou metodu — GRASP dává objektivní kritéria: Information Expert, Low Coupling, High Cohesion a další.
Přesně devět vzorů: Information Expert, Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations. Každý popisuje jeden aspekt přidělování odpovědnosti mezi objekty.
Začněte s SOLID — je jednodušší a široce známý. Poté se učte GRASP, který dává konkrétní kritéria pro aplikaci SOLID. GRASP vysvětluje „jak", SOLID vysvětluje „co". Ideálně používejte obě sady při code review.
ViewModel — Controller + Pure Fabrication. Repository — Information Expert + Pure Fabrication. Rozhraní pro API — Protected Variations. DI framework (Hilt) — Indirection. GRASP — nejsou implementační vzory, ale zdůvodnění architektonických rozhodnutí.
V praxi se nejčastěji používají Information Expert (kam umístit metodu), High Cohesion (nepřetěžuj třídu), Low Coupling (minimalizuj závislosti) a Controller (odděl UI od logiky). Pure Fabrication je důležité pro pochopení vrstev Repository a ViewModel.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také