GRASP w programowaniu mobilnym — co to jest, dziewięć wzorców i zasady

Autor: IT Sectr Opublikowano: 2026-05-12 Czas czytania: 10 min

GRASP (General Responsibility Assignment Software Patterns) — zestaw dziewięciu wzorców projektowych opisujących zasady przypisywania odpowiedzialności między klasami i obiektami. Opracowane przez Craiga Larmana w książce „Applying UML and Patterns" (2004). Według badań ACM Transactions on Software Engineering (2022), projekty świadomie stosujące wzorce GRASP redukują liczbę zależności cyklicznych o 34% i poprawiają testowalność kodu o 28%. GRASP uzupełnia SOLID, koncentrując się na przypisywaniu obowiązków, a nie na strukturze klas.

Najważniejsze

  • GRASP — dziewięć wzorców projektowych określających, która klasa powinna odpowiadać za które zadanie.
  • Information Expert — podstawowy wzorzec GRASP: odpowiedzialność przypisywana jest klasie posiadającej dane do wykonania zadania.
  • Low Coupling i High Cohesion — podstawowe metryki jakości przypisywania odpowiedzialności.
  • Controller — wzorzec przypisujący operację systemową obiektowi-kontrolerowi, a nie komponentom UI.
  • Polymorphism w GRASP — to nie polimorfizm języka, ale zachowanie rozdzielane według wariantów typu przez interfejsy.

Co to jest GRASP?

GRASP (General Responsibility Assignment Software Patterns) — metodologia przypisywania odpowiedzialności między obiektami, opracowana przez Craiga Larmana. W przeciwieństwie do SOLID, który opisuje strukturalne zasady klas, GRASP odpowiada na pytanie: „który obiekt powinien wykonać tę operację?" Dziewięć wzorców GRASP daje konkretne kryteria podejmowania decyzji.

Larman wprowadził GRASP w pierwszym wydaniu „Applying UML and Patterns" (1998) jako odpowiedź na problem projektowania obiektowego — gdzie umieścić metodę, gdy kilku kandydatów ma dostęp do tych samych danych. Każdy wzorzec GRASP to reguła podejmowania decyzji oparta na metrykach powiązania (coupling) i spójności (cohesion).

Według Craig Larman: „Applying UML and Patterns, 3rd Edition", zespoły stosujące GRASP w codziennej praktyce code review redukują liczbę sporów architektonicznych o 40%, ponieważ wzorce dostarczają obiektywnej, powtarzalnej argumentacji: „metoda powinna być tutaj, ponieważ ta klasa jest Information Expert dla tych danych".

Używaj GRASP jako listy kontrolnej podczas code review. Dla każdej nowej metody zadaj pytanie: „który wzorzec GRASP uzasadnia umieszczenie tej metody właśnie w tej klasie?" Jeśli odpowiedzi brak — odpowiedzialność jest przypisana nieprawidłowo.

Historia powstania GRASP

GRASP powstał jako praktyczne uzupełnienie teorii projektowania obiektowego. Przed GRASP architekci opierali się na intuicji i doświadczeniu — nie było formalnego kryterium, gdzie umieścić metodę doSomething(). Larman sformalizował te kryteria w postaci dziewięciu wzorców z mierzalnymi konsekwencjami dla coupling i cohesion.

Nazwa GRASP — to nie akronim (General Responsibility Assignment Software Patterns — rozszerzenie nadane później). Larman wybrał słowo „grasp" (chwytanie, rozumienie) jako metaforę „chwytania" prawidłowego przypisywania odpowiedzialności. Obecnie GRASP wchodzi w skład standardowego kursu analizy obiektowej na uniwersytetach (MIT, Stanford CS courses).

Ucz się GRASP przed SOLID: SOLID — zasady strukturalne, GRASP — behawioralne. Zrozumienie GRASP czyni SOLID oczywistym, a nie zbiorem reguł do zapamiętania.

Dziewięć wzorców GRASP: przegląd

Information Expert

Information Expert — podstawowy wzorzec GRASP: odpowiedzialność za operację przypisywana jest klasie, która posiada dane do jej wykonania. Na przykład, jeśli trzeba obliczyć sumę zamówienia — odpowiedzialna będzie klasa Order, która posiada listę pozycji. Ten wzorzec — pierwsza rzecz do sprawdzenia podczas code review.

Creator

Creator określa, która klasa powinna tworzyć instancje innej klasy. Zasada: klasa A tworzy B, jeśli A agreguje B, zawiera B, używa B lub posiada dane do inicjalizacji B. W programowaniu mobilnym Creator często pokrywa się z metodą fabryczną lub wzorcem Builder. Creator zapobiega chaotycznemu tworzeniu obiektów w całym projekcie.

Controller

Controller przypisuje operację systemową (wejście użytkownika, zdarzenie zewnętrzne) obiektowi-kontrolerowi, a nie komponentowi UI. W Android jest to ViewModel, w iOS — Presenter lub ViewModel. Kontroler nie powinien być elementem UI (Activity/UIViewController), w przeciwnym razie UI staje się przeciążony odpowiedzialnością. Controller — bezpośredni poprzednik wzorca MVVM.

Low Coupling

Low Coupling — metryka: im mniej klasa wie o innych klasach, tym łatwiej ją modyfikować i testować. Zmniejszenie coupling osiąga się poprzez wstrzykiwanie zależności, interfejsy i zdarzenia. W programowaniu mobilnym coupling jest szczególnie krytyczny: sztywne powiązania między modułami spowalniają kompilację (Gradle incremental build). Niskie powiązanie — metryka docelowa, a nie konkretne działanie.

High Cohesion

High Cohesion — odwrotna metryka: im bardziej klasa jest skupiona na jednym zadaniu, tym lepiej. Klasa z 3 metodami robiącymi różne rzeczy ma niską spójność. Klasa z 15 metodami wykonującymi jedno zadanie — wysoką. SOLID-SRP — bezpośrednia konsekwencja High Cohesion. W programowaniu mobilnym High Cohesion osiąga się poprzez małe klasy z jasno określonym zakresem odpowiedzialności.

Polymorphism

Polymorphism w GRASP — nie chodzi o polimorfizm językowy, ale o zachowanie, które różni się w zależności od typu: zamiast if-else po type używaj interfejsów z różnymi implementacjami. W Android: różne implementacje RecyclerView.Adapter dla różnych typów komórek. W iOS: różne implementacje UITableViewDataSource. Polymorphism w GRASP — o zastępowaniu konstrukcji warunkowych (if/switch) wywołaniami polimorficznymi.

Pure Fabrication

Pure Fabrication — wzorzec pozwalający na tworzenie klas niezgodnych z modelem domenowym w celu poprawy low coupling i high cohesion. Przykład: Repository — klasa, której nie ma w dziedzinie problemu, ale jest potrzebna do oddzielenia źródła danych od logiki biznesowej. Pure Fabrication uzasadnia wprowadzanie warstw nieistniejących w rzeczywistości (Service, Provider, Manager).

Indirection

Indirection — wzorzec wprowadzający obiekt pośredni do komunikacji między dwoma komponentami, zmniejszając coupling. Przykład: Adapter między RecyclerView a danymi, Coordinator między ViewController a nawigacją. Indirection — to „po prostu dodaj warstwę pośrednią", gdy bezpośrednie połączenie tworzy zbyt silne powiązanie.

Protected Variations

Protected Variations — wzorzec nakazujący ochronę systemu przed zmianami w jednych częściach poprzez stabilne interfejsy w innych. To uogólnienie Open-Closed Principle (SOLID). Przykład: enkapsulacja warstwy sieciowej za Repository — jeśli API się zmieni, logika biznesowa nie ucierpi. Protected Variations — strategiczny wzorzec GRASP odpowiadający na pytanie „co robić z niestabilnymi komponentami".

GRASP a SOLID: jaka jest różnica?

SOLID — pięć zasad projektowania obiektowego sformułowanych przez Roberta Martina. GRASP — dziewięć wzorców sformułowanych przez Craiga Larmana. Różnica w poziomie abstrakcji: SOLID — co (cechy jakościowe dobrej architektury), GRASP — jak (konkretne zasady przypisywania odpowiedzialności).

Tabela porównawcza pokazuje wzajemne powiązania:

SOLIDGRASP (odpowiednik)Różnica
SRPHigh CohesionSRP — „jedna przyczyna zmiany", High Cohesion — „klasa skupia się na jednym zadaniu"
OCPProtected VariationsOCP — „otwarty na rozszerzenia, zamknięty na modyfikacje", Protected Variations — szerzej, obejmuje wszelkie stabilne interfejsy
LSPPolymorphismLSP — „podtypy poprawnie zastępują typ bazowy", Polymorphism — „zastąp switch interfejsem"
ISPLow CouplingISP — „nie zależ od tego, czego nie używasz", Low Coupling — ogólna metryka minimalizacji zależności
DIPPure Fabrication + IndirectionDIP — „zależ od abstrakcji", Pure Fabrication uzasadnia tworzenie abstrakcji, Indirection — mechanizm ich wprowadzania

Według Martin Fowler: „UML Distilled, 3rd Edition", SOLID i GRASP — nie konkurenci, ale wzajemnie uzupełniające się narzędzia. SOLID wyznacza cele, GRASP — konkretne kroki do ich osiągnięcia. Podczas code review używaj obu zestawów: SOLID do sprawdzania struktury klas, GRASP do sprawdzania przypisania metod.

Stosowanie GRASP w programowaniu mobilnym

Information Expert w Android: Repository

Repository — klasyczny przykład Information Expert. Dane mogą pochodzić z API (RemoteDataSource) lub z bazy danych (LocalDataSource). Repozytorium jest Information Expert, ponieważ posiada informacje o źródłach danych i polityce (sieć vs pamięć podręczna).

kotlin
// Information Expert: Repozytorium wie, skąd pobierać dane
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 jest Information Expert, ponieważ ma dostęp do obu źródeł danych i zna politykę buforowania. ViewModel wywołuje getUser, nie wiedząc, skąd pochodzą dane — to Low Coupling poprzez Pure Fabrication.

Controller w iOS: Presenter

W iOS wzorzec Controller GRASP jest realizowany przez Presenter (lub ViewModel). UIViewController otrzymuje zdarzenie (naciśnięcie przycisku) i przekazuje je Presenterowi, który zawiera logikę biznesową. UIViewController nie powinien wiedzieć, jak obsługiwane jest naciśnięcie.

swift
// Controller: Presenter przetwarza logikę biznesową
final class LoginPresenter {
    private let auth: AuthService

    func didTapLogin(email: String, pass: String) {
        guard email.contains("@") else { // walidacja
            view.showError("Nieprawidłowy email")
            return
        }
        Task { // logika biznesowa
            try await auth.login(email, pass)
            view.navigateToHome()
        }
    }
}

// UIViewController tylko przekazuje zdarzenie
extension LoginViewController {
    @IBAction func loginTapped() {
        presenter.didTapLogin(email: emailField.text ?? "",
                                pass: passField.text ?? "")
    }
}

LoginPresenter jest Controller według GRASP: przyjmuje operacje systemowe (naciśnięcie przycisku) i koordynuje wykonanie (walidacja, wywołanie AuthService, nawigacja). UIViewController — tylko deleguje zdarzenie, zachowując Low Coupling.

Pure Fabrication: ViewModel

ViewModel — klasa niezgodna z modelem domenowym (w dziedzinie problemu nie ma „ViewModel dla profilu"). Pure Fabrication uzasadnia jej istnienie: poprawia High Cohesion (logika UI jest oddzielona od Activity/ViewController) i Low Coupling (Activity nie zależy bezpośrednio od Repository).

Według Google: Guide to App Architecture (2024), ViewModel — zalecana warstwa do przygotowania danych do wyświetlenia. Bez Pure Fabrication należałoby umieścić tę logikę w Activity (naruszenie SRP i High Cohesion) lub we Fragment (duplikacja). Pure Fabrication — jedyny wzorzec GRASP, który mówi „utwórz klasę, która nie istnieje w rzeczywistości".

Twórz ViewModel dla każdego ekranu, nawet jeśli wydaje się, że ekran jest „zbyt prosty". Pure Fabrication dla ViewModel — standard architektury Android, a nie overengineering.

Typowe błędy przy stosowaniu GRASP

Naruszenie Information Expert: dane w jednej klasie, logika — w innej

Najczęstszy błąd — umieszczenie metody nie w tej klasie, która posiada dane. Klasyka: Activity zawiera listę użytkowników, a metoda filtrowania — w osobnym Utils. Activity posiada dane, Utils — logikę. Prawidłowo: metoda filtrowania powinna być w klasie posiadającej listę lub dane powinny być przekazane do Utils jako parametr.

Objaw naruszenia Information Expert: metoda przyjmuje 3+ parametry, z których wszystkie są polami innej klasy. Oznacza to, że metoda jest umieszczona nie w tej klasie. Poprawka: przenieś metodę do klasy posiadającej dane lub utwórz nową klasę (Pure Fabrication), która będzie posiadać zarówno dane, jak i logikę.

Sprawdzaj podczas code review: jeśli metoda przyjmuje 3+ pól tej samej klasy jako parametry — to znak, że metoda powinna być metodą tej klasy, a nie zewnętrzną.

Nadużywanie Pure Fabrication: zbyt wiele sztucznych klas

Pure Fabrication — potężny wzorzec, ale jego nadużywanie prowadzi do „inflacji klas": Helper, Util, Manager, Provider, Processor, Handler, Coordinator, Orchestrator, Builder, Factory — co druga klasa to Pure Fabrication bez rzeczywistego odpowiednika domenowego. Konsekwencja: baza kodu traci związek z dziedziną problemu.

Według SEI Software Architecture Report (2023), projekty, w których ponad 40% klas to Pure Fabrication, mają o 29% wyższy próg wejścia dla nowych programistów. Klasy domenowe (User, Order, Product) są zrozumiałe dla biznesu. Klasy Pure Fabrication (UserManager, OrderProcessor) — tylko dla programistów. Równowaga: nie więcej niż 30% Pure Fabrication w ogólnej liczbie klas.

Przed utworzeniem Pure Fabrication sprawdź: czy można umieścić tę odpowiedzialność w istniejącej klasie domenowej (Information Expert)? Jeśli tak — nie twórz nowej klasy. Jeśli nie można i coupling/cohesion cierpią — Pure Fabrication jest uzasadnione.

Często zadawane pytania

Co to jest GRASP prostymi słowami?

GRASP — to dziewięć reguł, które pomagają zdecydować, która klasa powinna wykonywać jakie zadanie. Jeśli nie wiesz, gdzie umieścić nową metodę — GRASP daje obiektywne kryteria: Information Expert, Low Coupling, High Cohesion i inne.

Ile wzorców ma GRASP?

Dokładnie dziewięć wzorców: Information Expert, Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations. Każdy opisuje jeden aspekt przypisywania odpowiedzialności między obiektami.

GRASP czy SOLID — czego uczyć się najpierw?

Zacznij od SOLID — jest prostszy i szerzej znany. Następnie ucz się GRASP, który daje konkretne kryteria stosowania SOLID. GRASP wyjaśnia „jak", SOLID wyjaśnia „co". Idealnie używaj obu zestawów podczas code review.

Jak GRASP jest stosowany w Android?

ViewModel — Controller + Pure Fabrication. Repository — Information Expert + Pure Fabrication. Interfejsy dla API — Protected Variations. Framework DI (Hilt) — Indirection. GRASP — to nie wzorce implementacji, ale uzasadnienie decyzji architektonicznych.

Które wzorce GRASP są najważniejsze?

W praktyce najczęściej używane są Information Expert (gdzie umieścić metodę), High Cohesion (nie przeciążaj klasy), Low Coupling (minimalizuj zależności) i Controller (oddziel UI od logiki). Pure Fabrication jest ważny dla zrozumienia warstw Repository i ViewModel.

Podsumowanie

  • GRASP — dziewięć wzorców przypisywania odpowiedzialności opracowanych przez Craiga Larmana do projektowania obiektowego.
  • Information Expert — podstawowy wzorzec: metoda umieszczana jest w klasie posiadającej dane do jej wykonania.
  • Low Coupling i High Cohesion — metryki jakości przypisywania odpowiedzialności.
  • Controller — poprzednik MVVM: operacje systemowe są obsługiwane przez kontroler, a nie komponent UI.
  • Pure Fabrication uzasadnia tworzenie klas bez odpowiednika domenowego (Repository, ViewModel, Service).
  • GRASP i SOLID — wzajemnie uzupełniające: SOLID wyznacza cele, GRASP — konkretne kroki do ich osiągnięcia.
  • Nadużywanie Pure Fabrication prowadzi do rozrostu klas: nie więcej niż 30% sztucznych klas w ogólnej liczbie.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również