AOP (Aspect-Oriented Programming, aspekt yönümlü proqramlaşdırma) — kəsişən funksionallığı (cross-cutting concerns) ayrı modullara — aspektlərə ayıran paradiqma. Loglama, giriş hüquqlarının yoxlanması, tranzaksiyaların idarə edilməsi və keşləmə — AOP-nin əsas biznes məntiqindən təcrid etdiyi tipik tapşırıqlar. Spring Framework AOP Documentation, 2025-ə görə, AOP pointcut (kəsmə nöqtəsi) və advice (məsləhət) mexanizmləri vasitəsilə icra zamanı və ya kompilasiya mərhələsində kodu yaxalayan şəkildə həyata keçirilir.
Əsaslar
AOP (Aspect-Oriented Programming) — obyekt yönümlü proqramlaşdırmanı (OOP) tamamlayan paradiqmadır. OOP kodu obyektlər və siniflər ətrafında təşkil edirsə, AOP tətbiqin bütün qatlarına nüfuz edən kəsişən tapşırıqları (cross-cutting concerns) ayırır: loglama, audit, tranzaksiyalar, təhlükəsizlik və performans.
AOP termini 1997-ci ildə Xerox PARC tədqiqat mərkəzində Gregor Kiczales və Crispin Wykes tərəfindən təqdim edilmişdir. İlk tətbiq — AspectJ — 2001-ci ildə Java genişlənməsi kimi ortaya çıxmışdır. Bu gün AOP ən böyük freymvorklara daxildir: Spring AOP (Java/Kotlin), JBoss AOP, həmçinin Objective-C və Swift-in runtime mexanizmləri vasitəsilə həyata keçirilir.
AOP-nin həll etdiyi əsas problem — kodun dolaşıqlığı (tangling). AOP olmadan biznes məntiqi metodlarında boilerplate olur: hər bir xidmət metodunda eyni loglama sətirləri, giriş yoxlamaları və tranzaksiyalar təkrarlanır. AOP bu kodu aspektlərə çıxarır, biznes məntiqini təmiz və domen sahəsinə fokuslanmış saxlayır.
AOP dörd əsas anlayışa əsaslanır: Join Point (birləşmə nöqtəsi), Pointcut (kəsmə), Advice (məsləhət) və Aspect (aspekt). Join Point — advice-in tətbiq oluna biləcəyi proqramda yer: metod çağırışı, sahəyə müraciət, nüsxənin yaradılması. Pointcut — join point-ları seçən predikat: məsələn, @Loggable annotasiyası ilə işarələnmiş bütün xidmət qatı metodları.
Advice növləri aspekt kodunun nə vaxt icra olunacağını müəyyən edir:
Aspect — pointcut və advice-i birləşdirən modul. AspectJ-də aspekt @Aspect annotasiyası ilə sinif kimi yazılır. Sinif daxilində hər bir metod pointcut ifadəsi olan advice-dir. Bu yanaşma kəsişən funksionallığı hədəf sinifləri dəyişmədən deklarativ şəkildə konfiqurasiya etməyə imkan verir.
Weaving — advice-in hədəf siniflərə yerləşdirilməsi prosesi. Üç növ weaving mövcuddur: compile-time (kompilasiya mərhələsində), load-time (sinif yüklənərkən) və runtime (icra zamanı). AspectJ AJC (AspectJ Compiler) vasitəsilə compile-time weaving-dən, Spring AOP isə JDK və ya CGLIB dinamik proksiləri vasitəsilə runtime proxy-based weaving-dən istifadə edir.
// Spring AOP və @Aspect ilə AOP nümunəsi
@Aspect
class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
fun logMethodCall(joinPoint: ProceedingJoinPoint): Any? {
val methodName = joinPoint.signature.name
val args = joinPoint.args
println("Metod çağırışı: $methodName, arqumentlər: ${args.contentToString()}")
val result = joinPoint.proceed()
println("$methodName metodu qaytardı: $result")
return result
}
}
Nümunədə @Around advice com.example.service paketindəki BÜTÜN metod çağırışlarını yaxalayır. execution(* ..*.*(..)) pointcut ifadəsi istənilən parametrləri olan istənilən metodu seçir. joinPoint.proceed() orijinal metodu çağırır — aspekt əvvəl və sonra loglama əlavə edərək icranı idarə edir. Spring Framework-ə görə, belə advice-in hər çağırışa əlavə yükü 1–5 µs təşkil edir.
Runtime proxy (Spring AOP) aspektin hədəflədiyi hər bir bean üçün alt sinif və ya interfeys proksi yaradır. Proksi çağırılan metodları yaxalayır və advice tətbiq edir. Çatışmazlıq — proksi final sinifləri və özəl metodlarla işləmir. Compile-time weaving (AspectJ) bayt kodunu birbaşa dəyişdirir, özəl və statik daxil olmaqla bütün çağırışları emal edir. Bunun əvəzi — daha mürəkkəb quruluş konfiqurasiyası və daha az yenidən konfiqurasiya elastikliyidir.
Android-də AOP AspectJ, runtime weaving kitabxanaları (Spring AOP istifadə edilmir — bean konteynerləri Android-ə daxil deyil) və bytecode manipulation (ASM, Gradle Plugin) vasitəsilə həyata keçirilir. Ən populyar variant — Android tətbiqinin qurulması mərhələsində compile-time weaving yerinə yetirən Gradle plaginli AspectJ-dir.
// Android üçün AspectJ aspekti: icazə yoxlaması
@Aspect
class PermissionAspect {
@Before("execution(@PermissionRequired * *(..))")
fun checkPermission(joinPoint: JoinPoint) {
val annotation = joinPoint.signature
.declaringType.
getDeclaredMethod(joinPoint.signature.name)
.getAnnotation(PermissionRequired::class.java)
val permission = annotation.value
if (!ContextCompat.checkSelfPermission(
context, permission)) {
throw SecurityException("Permission $permission denied")
}
}
}
Kodda @Before aspekti @PermissionRequired annotasiyası olan metod çağırışlarını yaxalayır. Hər bir metoda əl ilə checkSelfPermission yazmaq əvəzinə, tərtibatçı bir annotasiya əlavə edir. AspectJ weaver kompilasiya mərhələsində bayt kodunu dəyişdirir: hər annotasiyalı metoda orijinal koddan əvvəl aspekt çağırışı daxil edilir.
Android-də AOP məhdudiyyətləri: AspectJ plagin (jetifier) yalnız AGP 7.x-ə qədər uyğundur. AGP 8.0-dan etibarən Google bytecode manipulation üçün Transform API ilə ASM-i tövsiyə edir. Firebase Performance Monitoring və JaCoCo məhz bu yanaşmadan istifadə edir. Kotlin Compiler Plugin — AspectJ olmadan AOP-ni Kotlin kompilasiya mərhələsində IR-transformasiyalar vasitəsilə həyata keçirməyə imkan verən başqa bir mexanizmdir.
AspectJ @Aspect, @Before, @Around annotasiyaları ilə deklarativ API təqdim edir — aspekt kodu oxunaqlı və davamlıdır. ASM bayt kodu ilə aşağı səviyyəli iş tələb edir: sinif ziyarətçiləri, yığın analizatorları və təlimat dəyişiklikləri. Sadə tapşırıqlar üçün (loglama, icazə yoxlaması) AspectJ daha səmərəlidir. Mürəkkəb transformasiyalar üçün (tətbiqdə hər çağırışın instrumentasiyası) ASM bayt kodu üzərində tam nəzarət verir.
iOS-da AOP tarixən Objective-C Runtime — method swizzling və message forwarding vasitəsilə həyata keçirilir. Aspects kitabxanası (2014) sadə API təqdim edir: [UIViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:...]. Lakin Aspects və oxşar kitabxanaların məhdudiyyətləri var: təmiz Swift sinifləri ilə işləmir və bir-biri ilə ziddiyyət təşkil edə bilər.
Müasir yanaşma — InterposeKit (Swift, 2023-cü ildə açıq mənbə). Kitabxana Objective-C Runtime olmadan metodların təhlükəsiz yaxalanması üçün Swift runtime və fishhook-dan istifadə edir. InterposeKit Swift metodlarını, @objc və C funksiyalarını dəstəkləyir, tip-təhlükəsiz API-yə malikdir və ikiqat yaxalanmanın qarşısını alır. Alternativ — Combine Publishers (Swift), reaktiv paradiqmada AOP-ni əvəz edir.
SwiftUI AOP ehtiyacını aradan qaldırır: .onAppear, .onReceive, .task modifikatorları kəsişən davranışı deklarativ şəkildə əlavə edir. WWDC 2023-ə görə, Apple yeni layihələrdə kəsişən concerns üçün AOP əvəzinə SwiftUI modifikatorları və Custom Attributes istifadəsini tövsiyə edir. UIKit layihələrində Runtime vasitəsilə AOP monitorinq (viewDidAppear swizzling) və mərkəzləşdirilmiş loglama üçün əsaslı olaraq qalır.
AOP OOP-ni əvəz etmir, onu tamamlayır. OOP siniflər və obyektlər vasitəsilə biznes məntiqinin modulluğunu təmin edir. AOP OOP-nin təkrarlanmadan təcrid edə bilmədiyi kəsişən concerns-ləri modullaşdırır. İdeal tətbiq əsas arxitektura üçün OOP-dən, infrastruktur tapşırıqları üçün isə AOP-dən istifadə edir.
| Xarakteristika | OOP | AOP |
|---|---|---|
| Modulluq vahidi | Sinif / obyekt | Aspekt |
| Diqqət | Biznes məntiqi, məlumatlar | Kəsişən funksionallıq |
| Nümunələr | UserService, OrderController | LoggingAspect, SecurityAspect |
| Təkrar istifadə | Miras, kompozisiya | Aspekt bir çox siniflərə tətbiq olunur |
| Bağlılıq | Sinif daxilində yüksək | Aşağı (aspekt hədəf sinifdən asılı deyil) |
| Test etmə | Hər sinif üçün vahid testlər | Aspektin hədəf koddan ayrıca test edilməsi |
AOP nə vaxt seçilməlidir: hər metoda təkrarlanan boilerplate görürsünüzsə (logger.info, securityCheck, transaction.begin/commit), kəsişən davranışın dəyişdirilməsi yüzlərlə sinfin dəyişdirilməsini tələb edirsə, refaktoring olmadan legacy layihəyə monitorinq tətbiq edirsinizsə. Nə vaxt SEÇMƏMƏLİ: sadə CRUD tətbiqləri üçün, burada weaving yükü əsaslandırılmır; komanda paradiqmanı zəif bilirsə (pis yazılmış aspekt təkrarlanan koddan daha çətin debug olunur).
AOP arxitektura yanaşmasını dəyişir: kəsişən funksionallıq artıq qatlar üzrə yayılmır, aspektlərdə toplanır. Bu modulluğu yaxşılaşdırır, lakin gizli asılılıqlar yaradır — tərtibatçı aspekti oxumadan metodun advice tərəfindən yaxalandığını görmür. Pointcut ifadələrini sənədləşdirmək və aspektləri yalnız infrastruktur qatı ilə məhdudlaşdırmaq, AOP-ni biznes məntiqinə tətbiq etməmək tövsiyə olunur.
Google Scholar (2024) tədqiqatına görə, AOP layihələrində təmiz OOP həlləri ilə müqayisədə 35% daha az təkrarlanan kod sətirləri var. Bununla belə, advice-in gizli icrası səbəbindən aspekt üzrə səhvlərin sayı sinif üzrə olandan 2 dəfə yüksəkdir. AOP-dən yalnız infrastruktur tapşırıqları üçün istifadə etmək və aspektləri hərtərəfli testlərlə əhatə etmək tövsiyə olunur.
Tez-tez soruşulan suallar
Method swizzling — dispatch table-da IMP-nin dəyişdirilməsi üçün konkret runtime texnikasıdır. AOP — swizzling-dən yaxalama mexanizmi kimi istifadə edə bilən, lakin həmçinin compile-time weaving, proxy yaxalama və code generation daxil olan daha geniş paradiqmadır. Swizzling — tətbiq, AOP — konsepsiya.
Bütün şəbəkə sorğularının loglanması (HTTP-logg), giriş hüquqlarının yoxlanması (icazə yoxlama aspekti), performans monitorinqi (metodların icra müddətinin ölçülməsi), verilənlər bazası tranzaksiyaları (avtomatik açma/bağlama), nəticələrin keşlənməsi, ekran analitikası (avtomatik screen view göndərilməsi).
Bəli, AOP hər yaxalanmış çağırışa əlavə yük gətirir. Runtime weaving (Spring AOP) — proksi vasitəsilə hər çağırışa 1–5 µs. Compile-time weaving (AspectJ) — submikrosaniyəlik yük, çünki advice birbaşa hədəf metoduna daxil edilir. Kritik sahələr üçün (UI renderinq, animasiyalar) AOP tövsiyə edilmir.
KMP-nin daxili AOP infrastrukturu yoxdur. AspectJ yalnız JVM-də işləyir. Kotlin/Native və Kotlin/JS compile-time weaving dəstəkləmir. KMP üçün ümumi kodla kompilasiya mərhələsində çağırışların yaxalanması üçün Kotlin Compiler Plugin (IR-transformasiyalar) istifadə etmək tövsiyə olunur.
SwiftUI modifikatorları (.onAppear, .task) və Compose effektləri (LaunchedEffect, SideEffect) UI məntiqi üçün AOP-ni əvəz edir. Interceptor nümunəsi (OkHttp Interceptor, Ktor Pipeline) — şəbəkə qatı üçün deklarativ yaxalama. Functional composition (Kotlin Coroutines, RxJava) — yaxalama əvəzinə kompozisiya.
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