GRASP (General Responsibility Assignment Software Patterns) — een set van negen ontwerppatronen die de principes van verantwoordelijkheidstoewijzing tussen klassen en objecten beschrijven. Ontwikkeld door Craig Larman in het boek „Applying UML and Patterns" (2004). Volgens onderzoek van ACM Transactions on Software Engineering (2022), verminderen projecten die bewust GRASP-patronen toepassen het aantal cyclische afhankelijkheden met 34% en verbeteren ze de testbaarheid van code met 28%. GRASP vult SOLID aan, met focus op het toewijzen van verantwoordelijkheden, niet op de structuur van klassen.
Kernpunten
GRASP (General Responsibility Assignment Software Patterns) — een methodologie voor het toewijzen van verantwoordelijkheid tussen objecten, ontwikkeld door Craig Larman. In tegenstelling tot SOLID, dat structurele principes van klassen beschrijft, beantwoordt GRASP de vraag: „welk object moet deze bewerking uitvoeren?" Negen patronen van GRASP geven concrete criteria voor besluitvorming.
Larman introduceerde GRASP in de eerste editie van „Applying UML and Patterns" (1998) als antwoord op het probleem van objectgeoriënteerd ontwerpen — waar plaats je een methode wanneer meerdere kandidaten toegang hebben tot dezelfde gegevens. Elk patroon van GRASP is een besluitvormingsregel gebaseerd op metingen van koppeling (coupling) en samenhang (cohesion).
Volgens Craig Larman: „Applying UML and Patterns, 3rd Edition" verminderen teams die GRASP gebruiken in de dagelijkse code review-praktijk het aantal architectuurgeschillen met 40%, omdat de patronen objectieve, reproduceerbare argumentatie bieden: „de methode moet hier zijn, omdat deze klasse de Information Expert is voor deze gegevens".
Gebruik GRASP als checklist tijdens code review. Stel voor elke nieuwe methode de vraag: „welk GRASP-patroon rechtvaardigt het plaatsen van deze methode precies in deze klasse?" Als er geen antwoord is — is de verantwoordelijkheid verkeerd toegewezen.
GRASP ontstond als een praktische aanvulling op de theorie van objectgeoriënteerd ontwerpen. Vóór GRASP vertrouwden architecten op intuïtie en ervaring — er was geen formeel criterium voor het plaatsen van een doSomething()-methode. Larman formaliseerde deze criteria in de vorm van negen patronen met meetbare gevolgen voor coupling en cohesion.
De naam GRASP — is geen afkorting (General Responsibility Assignment Software Patterns — later toegevoegde verklaring). Larman koos het woord „grasp" (begrijpen, grijpen) als metafoor voor het „begrijpen" van de juiste verantwoordelijkheidstoewijzing. Nu maakt GRASP deel uit van de standaardcursus objectgeoriënteerde analyse aan universiteiten (MIT, Stanford CS-cursussen).
Leer GRASP vóór SOLID: SOLID — structurele principes, GRASP — gedragsprincipes. Het begrijpen van GRASP maakt SOLID vanzelfsprekend, niet een set te onthouden regels.
Information Expert — het basispatroon van GRASP: verantwoordelijkheid voor een bewerking wordt toegewezen aan de klasse die de gegevens heeft om deze uit te voeren. Als bijvoorbeeld de som van een bestelling moet worden berekend — zal de klasse Order die de lijst met artikelen bevat verantwoordelijk zijn. Dit patroon — het eerste om te controleren tijdens code review.
Creator bepaalt welke klasse instanties van een andere klasse moet maken. Regel: klasse A creëert B als A B aggregeert, B bevat, B gebruikt of gegevens heeft voor initialisatie van B. In mobiele ontwikkeling valt Creator vaak samen met de fabrieksmethode of het Builder-patroon. Creator voorkomt chaotisch objectcreatie door het hele project.
Controller wijst de systeembewerking (gebruikersinvoer, externe gebeurtenis) toe aan een controller-object, niet aan een UI-component. In Android is dit ViewModel, in iOS — Presenter of ViewModel. De controller mag geen UI-element zijn (Activity/UIViewController), anders raakt UI overbelast met verantwoordelijkheid. Controller — de directe voorloper van het MVVM-patroon.
Low Coupling — meting: hoe minder een klasse weet over andere klassen, hoe gemakkelijker het is om deze te wijzigen en testen. Vermindering van coupling wordt bereikt door dependency injection, interfaces en gebeurtenissen. In mobiele ontwikkeling is coupling bijzonder kritisch: starre verbindingen tussen modules vertragen de compilatie (Gradle incremental build). Lage koppeling — doelmeting, geen concrete actie.
High Cohesion — omgekeerde meting: hoe meer een klasse is gefocust op één taak, hoe beter. Een klasse met 3 methoden die verschillende dingen doen heeft lage samenhang. Een klasse met 15 methoden die één taak uitvoeren — hoge samenhang. SOLID-SRP — direct gevolg van High Cohesion. In mobiele ontwikkeling wordt High Cohesion bereikt door kleine klassen met een duidelijk verantwoordelijkheidsgebied.
Polymorphism in GRASP — gaat niet over taalpolymorfisme, maar over gedrag dat varieert per type: gebruik in plaats van if-else op type interfaces met verschillende implementaties. In Android: verschillende implementaties van RecyclerView.Adapter voor verschillende celtypen. In iOS: verschillende implementaties van UITableViewDataSource. Polymorphism in GRASP — over het vervangen van conditionele constructies (if/switch) door polymorfe aanroepen.
Pure Fabrication — patroon dat het creëren van klassen toestaat die niet overeenkomen met het domeinmodel om low coupling en high cohesion te verbeteren. Voorbeeld: Repository — een klasse die niet bestaat in het probleemdomein, maar nodig is om de gegevensbron van de bedrijfslogica te scheiden. Pure Fabrication rechtvaardigt de introductie van lagen die niet in de werkelijkheid bestaan (Service, Provider, Manager).
Indirection — patroon dat een tussenliggend object introduceert voor communicatie tussen twee componenten, waardoor coupling wordt verminderd. Voorbeeld: Adapter tussen RecyclerView en gegevens, Coordinator tussen ViewController en navigatie. Indirection — betekent „voeg gewoon een tussenlaag toe" wanneer directe verbinding een te sterke koppeling creëert.
Protected Variations — patroon dat voorschrijft het systeem te beschermen tegen wijzigingen in sommige delen via stabiele interfaces in andere delen. Dit is een generalisatie van het Open-Closed Principle (SOLID). Voorbeeld: inkapseling van de netwerklaag achter Repository — als de API verandert, heeft de bedrijfslogica geen last. Protected Variations — het strategische GRASP-patroon dat de vraag beantwoordt „wat te doen met instabiele componenten".
SOLID — vijf principes van objectgeoriënteerd ontwerpen geformuleerd door Robert Martin. GRASP — negen patronen geformuleerd door Craig Larman. Het verschil zit in het abstractieniveau: SOLID — wat (kwalitatieve kenmerken van goede architectuur), GRASP — hoe (concrete regels voor verantwoordelijkheidstoewijzing).
De vergelijkingstabel toont de onderlinge samenhang:
| SOLID | GRASP (overeenkomst) | Verschil |
|---|---|---|
| SRP | High Cohesion | SRP — „één reden voor wijziging", High Cohesion — „klasse focust op één taak" |
| OCP | Protected Variations | OCP — „open voor uitbreiding, gesloten voor wijziging", Protected Variations — breder, omvat alle stabiele interfaces |
| LSP | Polymorphism | LSP — „subtypes vervangen basistype correct", Polymorphism — „vervang switch door interface" |
| ISP | Low Coupling | ISP — „hang niet af van wat je niet gebruikt", Low Coupling — algemene meting van minimalisatie van afhankelijkheden |
| DIP | Pure Fabrication + Indirection | DIP — „hang af van abstracties", Pure Fabrication rechtvaardigt het creëren van abstracties, Indirection — het mechanisme voor introductie ervan |
Volgens Martin Fowler: „UML Distilled, 3rd Edition" zijn SOLID en GRASP geen concurrenten, maar complementaire hulpmiddelen. SOLID stelt doelen, GRASP — concrete stappen om deze te bereiken. Gebruik beide sets tijdens code review: SOLID voor controle van de klassestructuur, GRASP voor controle van de methodeverdeling.
Repository — een klassiek voorbeeld van Information Expert. Gegevens kunnen komen van API (RemoteDataSource) of van de database (LocalDataSource). De repository is Information Expert, omdat het informatie bezit over gegevensbronnen en beleid (netwerk versus cache).
// Information Expert: Repository weet waar gegevens vandaan te halen
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 is Information Expert, omdat het toegang heeft tot beide gegevensbronnen en het caching-beleid kent. ViewModel roept getUser aan, zonder te weten waar de gegevens vandaan komen — dit is Low Coupling via Pure Fabrication.
In iOS wordt het Controller GRASP-patroon geïmplementeerd via Presenter (of ViewModel). UIViewController ontvangt de gebeurtenis (knopdruk) en geeft deze door aan de Presenter, die de bedrijfslogica bevat. UIViewController mag niet weten hoe de knopdruk wordt afgehandeld.
// Controller: Presenter verwerkt de bedrijfslogica
final class LoginPresenter {
private let auth: AuthService
func didTapLogin(email: String, pass: String) {
guard email.contains("@") else { // validatie
view.showError("Ongeldig e-mailadres")
return
}
Task { // bedrijfslogica
try await auth.login(email, pass)
view.navigateToHome()
}
}
}
// UIViewController geeft alleen de gebeurtenis door
extension LoginViewController {
@IBAction func loginTapped() {
presenter.didTapLogin(email: emailField.text ?? "",
pass: passField.text ?? "")
}
}
LoginPresenter is Controller volgens GRASP: het ontvangt systeembewerkingen (knopdruk) en coördineert de uitvoering (validatie, aanroep AuthService, navigatie). UIViewController — delegeert alleen de gebeurtenis, met behoud van Low Coupling.
ViewModel — een klasse die niet overeenkomt met het domeinmodel (in het probleemdomein bestaat geen „ViewModel voor profiel"). Pure Fabrication rechtvaardigt het bestaan ervan: het verbetert High Cohesion (UI-logica is gescheiden van Activity/ViewController) en Low Coupling (Activity is niet direct afhankelijk van Repository).
Volgens Google: Guide to App Architecture (2024) is ViewModel de aanbevolen laag voor het voorbereiden van gegevens voor weergave. Zonder Pure Fabrication zou deze logica in Activity (schending van SRP en High Cohesion) of in Fragment (duplicatie) moeten worden geplaatst. Pure Fabrication — het enige GRASP-patroon dat zegt „maak een klasse die niet in de werkelijkheid bestaat".
Maak ViewModel voor elk scherm, zelfs als het scherm „te eenvoudig" lijkt. Pure Fabrication voor ViewModel — de standaard van Android-architectuur, geen overengineering.
De meest voorkomende fout — het plaatsen van een methode in de klasse die niet de gegevens bezit. Klassiek: Activity bevat de lijst van gebruikers, maar de filteringsmethode — in een aparte Utils-klasse. Activity bezit de gegevens, Utils — de logica. Correct: de filteringsmethode moet in de klasse zijn die de lijst bezit, of de gegevens moeten als parameter aan Utils worden doorgegeven.
Symptoom van schending van Information Expert: de methode ontvangt 3+ parameters, allemaal velden van een andere klasse. Dit betekent dat de methode in de verkeerde klasse is geplaatst. Oplossing: verplaats de methode naar de klasse die de gegevens bezit of creëer een nieuwe klasse (Pure Fabrication) die zowel de gegevens als de logica zal bezitten.
Controleer tijdens code review: als een methode 3+ velden van dezelfde klasse als parameters ontvangt — is dit een teken dat de methode een methode van die klasse zou moeten zijn, niet van een externe.
Pure Fabrication — een krachtig patroon, maar misbruik ervan leidt tot „klasseninflatie": Helper, Util, Manager, Provider, Processor, Handler, Coordinator, Orchestrator, Builder, Factory — elke tweede klasse is Pure Fabrication zonder echte domeincorrespondentie. Gevolg: de codebase verliest de verbinding met het probleemdomein.
Volgens SEI Software Architecture Report (2023) hebben projecten waar meer dan 40% van de klassen Pure Fabrication is een 29% hogere instapdrempel voor nieuwe ontwikkelaars. Domeinklassen (User, Order, Product) zijn begrijpelijk voor het bedrijf. Pure Fabrication-klassen (UserManager, OrderProcessor) — alleen voor ontwikkelaars. Balans: niet meer dan 30% Pure Fabrication van het totale aantal klassen.
Controleer vóór het creëren van Pure Fabrication: kan deze verantwoordelijkheid in een bestaande domeinklasse (Information Expert) worden geplaatst? Zo ja — maak geen nieuwe klasse. Zo nee en coupling/cohesion lijden eronder — is Pure Fabrication gerechtvaardigd.
Veelgestelde vragen
GRASP — zijn negen regels die helpen beslissen welke klasse welk werk moet doen. Als u niet weet waar u een nieuwe methode moet plaatsen — geeft GRASP objectieve criteria: Information Expert, Low Coupling, High Cohesion en andere.
Precies negen patronen: Information Expert, Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations. Elk beschrijft één aspect van verantwoordelijkheidstoewijzing tussen objecten.
Begin met SOLID — het is eenvoudiger en breder bekend. Leer daarna GRASP, dat concrete criteria geeft voor de toepassing van SOLID. GRASP legt „hoe" uit, SOLID legt „wat" uit. Idealiter gebruik je beide sets tijdens code review.
ViewModel — Controller + Pure Fabrication. Repository — Information Expert + Pure Fabrication. Interfaces voor API — Protected Variations. DI-framework (Hilt) — Indirection. GRASP — zijn geen implementatiepatronen, maar de rationale voor architectonische beslissingen.
In de praktijk worden het meest gebruikt Information Expert (waar plaats je de methode), High Cohesion (overbelast de klasse niet), Low Coupling (minimaliseer afhankelijkheden) en Controller (scheid UI van logica). Pure Fabrication is belangrijk voor het begrijpen van de Repository- en ViewModel-lagen.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook