GRASP (General Responsibility Assignment Software Patterns) — siniflər və obyektlər arasında məsuliyyətin bölüşdürülməsi prinsiplərini təsvir edən doqquz dizayn nümunəsindən ibarət dəstdir. Craig Larman tərəfindən "Applying UML and Patterns" (2004) kitabında işlənib hazırlanmışdır. ACM Transactions on Software Engineering (2022) tədqiqatına görə, GRASP nümunələrini şüurlu şəkildə tətbiq edən layihələr tsiklik asılılıqların sayını 34% azaldır və kodun test edilə bilməsini 28% yaxşılaşdırır. GRASP SOLID-i tamamlayır, siniflərin strukturuna deyil, vəzifələrin təyin edilməsinə diqqət yetirir.
Əsas məqamlar
GRASP (General Responsibility Assignment Software Patterns) — Craig Larman tərəfindən işlənib hazırlanmış, obyektlər arasında məsuliyyətin bölüşdürülməsi metodologiyasıdır. Siniflərin struktur prinsiplərini təsvir edən SOLID-dən fərqli olaraq, GRASP suala cavab verir: "bu əməliyyatı hansı obyekt yerinə yetirməlidir?" Doqquz nümunə GRASP qərar qəbul etmək üçün konkret meyarlar verir.
Larman GRASP-ı "Applying UML and Patterns" (1998) birinci nəşrində obyekt yönümlü dizayn probleminə — bir neçə namizəd eyni məlumatlara çıxışı olduqda metodu hara yerləşdirmək sualına cavab olaraq təqdim etmişdir. Hər bir nümunə GRASP — birləşmə (coupling) və bütövlük (cohesion) ölçülərinə əsaslanan qərar qəbuletmə qaydasıdır.
Craig Larman: "Applying UML and Patterns, 3rd Edition"-ə görə, GRASP-ı gündəlik code review təcrübəsində istifadə edən komandalar memarlıq mübahisələrinin sayını 40% azaldır, çünki nümunələr obyektiv, təkrarlana bilən arqumentasiya verir: "metod burada olmalıdır, çünki bu sinif bu məlumatlar üçün Information Expert-dir".
GRASP-ı code review zamanı yoxlama siyahısı kimi istifadə edin. Hər yeni metod üçün sual verin: "hansı GRASP nümunəsi bu metodu məhz bu sinifdə yerləşdirməyi əsaslandırır?" Cavab yoxdursa — məsuliyyət səhv bölüşdürülüb.
GRASP obyekt yönümlü dizayn nəzəriyyəsinə praktiki əlavə olaraq yaranmışdır. GRASP-dan əvvəl arxitektorlar intuisiya və təcrübəyə əsaslanırdılar — doSomething() metodunu hara yerləşdirmək üçün formal meyar yox idi. Larman bu meyarları coupling və cohesion üçün ölçülə bilən nəticələri olan doqquz nümunə şəklində rəsmiləşdirmişdir.
GRASP adı — abbreviatur deyil (General Responsibility Assignment Software Patterns — sonradan verilmiş izah). Larman "grasp" sözünü (tutmaq, dərk etmək) məsuliyyətin düzgün bölüşdürülməsini "tutmaq" metaforası kimi seçmişdir. Hal-hazırda GRASP universitetlərdə (MIT, Stanford CS kursları) standart obyekt yönümlü analiz kursuna daxildir.
GRASP-ı SOLID-dən əvvəl öyrənin: SOLID — struktur prinsiplər, GRASP — davranış prinsipləri. GRASP-ı başa düşmək SOLID-i aydın edir, əzbərlənən qaydalar toplusu kimi yox.
Information Expert — əsas GRASP nümunəsi: əməliyyat üçün məsuliyyət onu yerinə yetirmək üçün məlumatlara sahib olan sinfə təyin edilir. Məsələn, sifarişin məbləğini hesablamaq lazımdırsa — məsuliyyət daşıyıcısı maddələr siyahısına sahib olan Order sinfi olacaq. Bu nümunə — code review zamanı yoxlanılacaq ilk şeydir.
Creator hansı sinfin digər sinfin instansiyalarını yaratmalı olduğunu müəyyən edir. Qayda: A sinfi B-ni yaradır, əgər A B-ni toplayırsa, B-ni ehtiva edirsə, B-dən istifadə edirsə və ya B-ni işə salmaq üçün məlumatlara sahibdirsə. Mobil inkişafda Creator tez-tez fabrik metodu və ya Builder nümunəsi ilə üst-üstə düşür. Creator layihə boyu xaotik obyekt yaradılmasının qarşısını alır.
Controller sistem əməliyyatını (istifadəçi girişi, xarici hadisə) UI komponentinə deyil, nəzarətçi obyektinə təyin edir. Android-də bu ViewModel, iOS-da — Presenter və ya ViewModel-dir. Nəzarətçi UI elementi (Activity/UIViewController) olmamalıdır, əks halda UI məsuliyyətlə həddən artıq yüklənir. Controller — MVVM nümunəsinin birbaşa sələfidir.
Low Coupling — ölçü: sinif digər siniflər haqqında nə qədər az bilirsə, onu dəyişdirmək və test etmək bir o qədər asandır. Coupling-in azaldılması asılılıqların enjeksiyonu, interfeyslər və hadisələr vasitəsilə əldə edilir. Mobil inkişafda coupling xüsusilə kritikdir: modullar arasında sərt əlaqələr kompilasiyanı ləngidir (Gradle incremental build). Aşağı birləşmə — hədəf ölçü, konkret hərəkət deyil.
High Cohesion — tərs ölçü: sinif nə qədər bir tapşırığa fokuslanıbsa, bir o qədər yaxşıdır. Müxtəlif şeylər edən 3 metodu olan sinif aşağı bütövlüyə malikdir. Bir tapşırığı yerinə yetirən 15 metodu olan sinif — yüksək bütövlüyə. SOLID-SRP — High Cohesion-in birbaşa nəticəsidir. Mobil inkişafda High Cohesion aydın məsuliyyət sahəsi olan kiçik siniflər vasitəsilə əldə edilir.
Polymorphism GRASP-da — dil polimorfizmi deyil, tiplərə görə dəyişən davranışdır: type üzrə if-else əvəzinə müxtəlif implementasiyaları olan interfeyslərdən istifadə edin. Android-də: müxtəlif hüceyrə tipləri üçün RecyclerView.Adapter-in müxtəlif implementasiyaları. iOS-da: müxtəlif UITableViewDataSource implementasiyaları. Polymorphism GRASP-da — şərti konstruksiyaların (if/switch) polimorf çağırışlarla əvəz edilməsidir.
Pure Fabrication — low coupling və high cohesion-i yaxşılaşdırmaq üçün domen modelinə uyğun olmayan siniflər yaratmağa icazə verən nümunədir. Nümunə: Repository — mövzu sahəsində olmayan, lakin məlumat mənbəyini biznes məntiqindən ayırmaq üçün lazım olan sinif. Pure Fabrication reallıqda mövcud olmayan təbəqələrin (Service, Provider, Manager) tətbiqini əsaslandırır.
Indirection — iki komponent arasında əlaqə üçün aralıq obyekt təqdim edərək coupling-i azaldan nümunədir. Nümunə: RecyclerView və məlumatlar arasında Adapter, ViewController və naviqasiya arasında Coordinator. Indirection — birbaşa əlaqə çox güclü birləşmə yaratdıqda "sadəcə aralıq təbəqə əlavə edin" deməkdir.
Protected Variations — sistemin bir hissəsindəki dəyişikliklərdən digər hissələrdəki sabit interfeyslər vasitəsilə qorunmasını əmr edən nümunədir. Bu Open-Closed Principle (SOLID) ümumiləşdirməsidir. Nümunə: şəbəkə təbəqəsinin Repository arxasında inkapsulyasiyası — API dəyişərsə, biznes məntiqi zərər görməz. Protected Variations — "qeyri-sabit komponentlərlə nə etməli" sualına cavab verən strateji GRASP nümunəsidir.
SOLID — Robert Martin tərəfindən formalaşdırılmış beş obyekt yönümlü dizayn prinsipidir. GRASP — Craig Larman tərəfindən formalaşdırılmış doqquz nümunədir. Fərq abstraksiya səviyyəsindədir: SOLID — nə (yaxşı arxitekturanın keyfiyyət xarakteristikaları), GRASP — necə (məsuliyyətin bölüşdürülməsinin konkret qaydaları).
Müqayisə cədvəli qarşılıqlı əlaqəni göstərir:
| SOLID | GRASP (uyğunluq) | Fərq |
|---|---|---|
| SRP | High Cohesion | SRP — "dəyişiklik üçün bir səbəb", High Cohesion — "sinif bir tapşırığa fokuslanır" |
| OCP | Protected Variations | OCP — "genişlənməyə açıq, dəyişikliyə qapalı", Protected Variations — daha geniş, hər hansı sabit interfeysləri əhatə edir |
| LSP | Polymorphism | LSP — "alt tiplər əsas tipi düzgün əvəz edir", Polymorphism — "switch-i interfeyslə əvəz edin" |
| ISP | Low Coupling | ISP — "istifadə etmədiyin şeydən asılı olma", Low Coupling — asılılıqların minimumlaşdırılmasının ümumi ölçüsü |
| DIP | Pure Fabrication + Indirection | DIP — "abstraksiyalardan asılı ol", Pure Fabrication abstraksiyaların yaradılmasını əsaslandırır, Indirection — onların tətbiqi mexanizmi |
Martin Fowler: "UML Distilled, 3rd Edition"-ə görə, SOLID və GRASP — rəqib deyil, bir-birini tamamlayan vasitələrdir. SOLID məqsədlər qoyur, GRASP — onlara çatmaq üçün konkret addımlar. Code review zamanı hər iki dəstdən istifadə edin: SOLID siniflərin strukturunu yoxlamaq üçün, GRASP metodların bölüşdürülməsini yoxlamaq üçün.
Repository — Information Expert-in klassik nümunəsidir. Məlumatlar API-dən (RemoteDataSource) və ya verilənlər bazasından (LocalDataSource) gələ bilər. Repozitoriya Information Expert-dir, çünki o, məlumat mənbələri və siyasət (şəbəkə vs keş) haqqında məlumata sahibdir.
// Information Expert: Repozitoriya məlumatları haradan götürəcəyini bilir
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 Information Expert-dir, çünki o, hər iki məlumat mənbəyinə çıxışa malikdir və keşləmə siyasətini bilir. ViewModel getUser-i çağırır, məlumatların haradan gəldiyini bilmədən — bu Pure Fabrication vasitəsilə Low Coupling-dir.
iOS-da Controller GRASP nümunəsi Presenter (və ya ViewModel) vasitəsilə həyata keçirilir. UIViewController hadisəni (düymənin basılması) qəbul edir və biznes məntiqi olan Presenter-ə ötürür. UIViewController basmanın necə işləndiyini bilməməlidir.
// Controller: Presenter biznes məntiqini emal edir
final class LoginPresenter {
private let auth: AuthService
func didTapLogin(email: String, pass: String) {
guard email.contains("@") else { // doğrulama
view.showError("Yanlış email")
return
}
Task { // biznes məntiqi
try await auth.login(email, pass)
view.navigateToHome()
}
}
}
// UIViewController yalnız hadisəni ötürür
extension LoginViewController {
@IBAction func loginTapped() {
presenter.didTapLogin(email: emailField.text ?? "",
pass: passField.text ?? "")
}
}
LoginPresenter GRASP-a görə Controller-dir: o, sistem əməliyyatlarını (düymə basılması) qəbul edir və icranı koordinasiya edir (doğrulama, AuthService çağırışı, naviqasiya). UIViewController — yalnız hadisəni ötürür, Low Coupling-i qoruyur.
ViewModel — domen modelinə uyğun olmayan sinifdir (mövzu sahəsində "profil üçün ViewModel" yoxdur). Pure Fabrication onun mövcudluğunu əsaslandırır: High Cohesion-i (UI məntiqi Activity/ViewController-dən ayrılır) və Low Coupling-i (Activity birbaşa Repository-dən asılı deyil) yaxşılaşdırır.
Google: Guide to App Architecture (2024)-ə görə, ViewModel — məlumatların göstərilməyə hazırlanması üçün tövsiyə olunan təbəqədir. Pure Fabrication olmadan bu məntiqi Activity-də (SRP və High Cohesion pozuntusu) və ya Fragment-də (təkrarlanma) yerləşdirmək lazım gələrdi. Pure Fabrication — "reallıqda olmayan sinif yaradın" deyən yeganə GRASP nümunəsidir.
Hər ekran üçün ViewModel yaradın, hətta ekran "çox sadə" görünsə belə. ViewModel üçün Pure Fabrication — Android arxitekturasının standartıdır, overengineering deyil.
Ən çox yayılmış səhv — metodun məlumatlara sahib olan sinifdə yerləşdirilməməsidir. Klassik: Activity istifadəçi siyahısını ehtiva edir, lakin filtrləmə metodu ayrıca Utils sinfindədir. Activity məlumatlara sahibdir, Utils — məntiqə. Düzgün: filtrləmə metodu siyahıya sahib olan sinifdə olmalıdır və ya məlumatlar Utils-ə parametr kimi ötürülməlidir.
Information Expert pozulmasının əlaməti: metod 3+ parametr qəbul edir, hamısı başqa sinfin sahələridir. Bu, metodun yanlış sinifdə yerləşdirildiyini göstərir. Düzəliş: metodu məlumatlara sahib olan sinfə köçürün və ya həm məlumatlara, həm də məntiqə sahib olacaq yeni sinif (Pure Fabrication) yaradın.
Code review zamanı yoxlayın: əgər metod eyni sinfin 3+ sahəsini parametr kimi qəbul edirsə — bu, metodun bu sinfin metodu olmalı olduğuna işarədir, kənar sinfin yox.
Pure Fabrication — güclü nümunədir, lakin ondan sui-istifadə "sinif inflyasiyasına" gətirib çıxarır: Helper, Util, Manager, Provider, Processor, Handler, Coordinator, Orchestrator, Builder, Factory — hər ikinci sinif real domen qarşılığı olmayan Pure Fabrication-dır. Nəticə: kod bazası mövzu sahəsi ilə əlaqəsini itirir.
SEI Software Architecture Report (2023)-ə görə, siniflərin 40%-dən çoxu Pure Fabrication olan layihələr yeni tərtibatçılar üçün 29% daha yüksək giriş həddinə malikdir. Domen sinifləri (User, Order, Product) biznes üçün başa düşüləndir. Pure Fabrication sinifləri (UserManager, OrderProcessor) — yalnız tərtibatçılar üçün. Tarazlıq: ümumi sinif sayının 30%-dən çox olmayan Pure Fabrication.
Pure Fabrication yaratmadan əvvəl yoxlayın: bu məsuliyyəti mövcud domen sinfində (Information Expert) yerləşdirmək olarmı? Olarsa — yeni sinif yaratmayın. Olmazsa və coupling/cohesion əziyyət çəkirsə — Pure Fabrication əsaslandırılmışdır.
Tez-tez verilən suallar
GRASP — hansı sinfin hansı işi görməli olduğuna qərar verməyə kömək edən doqquz qaydadır. Yeni metodu hara yerləşdirəcəyinizi bilmirsinizsə — GRASP obyektiv meyarlar verir: Information Expert, Low Coupling, High Cohesion və başqaları.
Düz doqquz nümunə: Information Expert, Creator, Controller, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations. Hər biri obyektlər arasında məsuliyyətin bölüşdürülməsinin bir aspektini təsvir edir.
SOLID ilə başlayın — daha sadə və daha geniş tanınır. Sonra GRASP-ı öyrənin, o, SOLID-in tətbiqi üçün konkret meyarlar verir. GRASP "necə"-ni, SOLID "nə"-yi izah edir. İdeal olaraq hər iki dəsti code review zamanı istifadə edin.
ViewModel — Controller + Pure Fabrication. Repository — Information Expert + Pure Fabrication. API üçün interfeyslər — Protected Variations. DI çərçivəsi (Hilt) — Indirection. GRASP — tətbiq nümunələri deyil, memarlıq qərarları üçün əsaslandırmadır.
Praktikada ən çox istifadə olunanlar Information Expert (metodu hara yerləşdirmək), High Cohesion (sinfi həddən artıq yükləmə), Low Coupling (asılılıqları minimumlaşdır) və Controller (UI-ni məntiqdən ayır). Pure Fabrication Repository və ViewModel təbəqələrini başa düşmək üçün vacibdir.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun