Yazan : Şadi Evren ŞEKER
Yazılım mühendisliğinde kullanılan bir programlama yaklaşımıdır. AOP olarak kısaltılmış halde de geçer. Türkçe literatüründe bağlam / cephe / kesit / görünüm yönelimli programlama kelimelerinin hepsi farklı kaynaklarda kullanılmıştır. 1990’lı yılların ortalarında özellikle JAVA ve nesne yönelimli programlama ihe ivme kazanmış bir yaklaşımdır.
Kısaca aop’yi tanımlamak gerekirse bir program geliştirilmesi sırasında iki farklı yaklaşım görülmektedir. Birinci tip yaklaşım fonksiyonel ve programın yapacağı işlere ait yaklaşımdır. Yani programı yazdığımızda ve program çalıştığında karşılayacağı ihtiyaçlar, yapacağı işlemler şeklindeki ve iş mantığı (business logic) olarak isimlendirilebilecek bakıştır. İkinci bakış ise teknik bakıştır (technicak concerns) yani programın çalıştığı ortam, işletim sistemi, veri tabanı gibi unsurlardır.
AOP kısaca bu iki unsurlar kümesinin birbirinden ayrılmasını ve bağlam adı altında modülerleştirilmesini söyler. Yani fonksiyonel unsurlar ile teknik unsurların birbirinden ayrılmasını daha sonra modüller kapsamında bu iki unsurun birleştirilmesini söyler.
AOP, OOP’nin yerini alabilir mi?
AOP yaklaşımı nesne yönelimli programlama dilleri (Object Oriented Programming, OOP) üzerinde geliştirilmektedir. Bu anlamda AOP ile OOP birbirini tam olarak ikame eden yaklaşımlar değildir. Ancak AOP yaklaşımı doğası gereği ortam olarak OOP destekleyen bir dile ihtiyaç duyar. Yani yaklaşım olarak bağlam yönelimli programlama (AOP) kullanılıyor olsa bile hâlâ sınıflar (class) yazmaya ve bu sınıfların metotlarını kodlamaya ihtiyaç vardır. AOP, bu sınıfların metotların veya özelliklerin sadece hangi bakış açısıyla modelleneceğini belirler. Yani bir proje tasarımı yapılırken sınıfların ve nesne yönelimli kodlama yaklaşımının uygulanması sırasında bakış yönelimli tercihler yapılabilir veya yapılmayabilir.
AOP’ye ne zaman ihtiyaç vardır?
Bilindiği üzere normalde bir program geliştirilme sürecinde OOP kullanılması pek çok açıdan avantajldır ve OOP ile pek çok farklı alanda ve farklı içerikte proje geliştirilmesi mümkündür. Ancak AOP’nin farkını anlamak ve OOP’nin limitlerini görmek açısından iki noktada OOP’nin yetersiz olduğunu ve AOP’ye ihtiyaç duyduğumuzu söyleyebiliriz.
- Kod yayılması (Code scattering)
- Kestirme Fonksiyonellikler (Crosscutting Functionalities)
Yukarıdaki bu iki durumda klasik OOP yaklaşımının AOP yaklaşımına göre geri olduğu söylenebilir.
Kod yayılımı (Code Scattering)
Bilindiği üzere nesne yönelimli programlama dillerinde nesneler arası ilişkiyi iki türlü ele alabiliriz.
- Çağıran nesneler (invoke)
- Çağrılan nesneler (invoked)
Yani bir nesne ile diğer bir nesne arasında bir protokol bulunuyorsa, bir nesne diğerinin bir fonksiyonunu (method) çağırıyor demektir. Bu durumda nesne yönelimli programlama yaklaşımı bize bu çağrılan nesne veya methodu hakkında kaygılanmamızı ve kapalı bir kutu gibi görüp (blackbox) beklediğimiz hizmeti almamızı söyler.
Ancak herhangi bir sebeple bu aradaki çağırma işlemini yapan ve protokolümüzün üzerine kurulu olduğu fonksiyonu değiştirecek olursak. Örneğin yeni bir parametre ekleyecek olursak. Bu durudma bütün çağıran nesnelerin de çağırma sırasındaki fonksiyonlarının değişmesi gerekir.
Yani bir metot’un paramtre sayısının değişmesi gibi bir durumda bütün bu metotu çağıran sınıflara müdahale edilmesi aslında geliştirme ve sonrada kodun yönetilmesi açısından güçlükler doğurur ve bu duruma kod yayılması (code scattering) ismi verilir
Kestirme Fonksiyonellikler (Crosscutting Functionalities)
Kestirme fonksiyonellik kısaca nesne yönelimli yaklaşımlarda bir nesnenin modellenmesi sırasında nesneye yüklenen fonksiyonelliğin birden fazla nesne tarafından paylaşılması durumudur. Yani A nesnesinin F fonksiyonunu yüklenmesini istiyorsak ancak bu F fonksiyonunu B,C gibi diğer nesneler de yükleniyorsa veya kontrol ediyorsa bu durumda aslında A nesnesinin tam modellendiği söylenemez. Her ne kadar OOP açısından tasarlamak ve kodlamak mümkün olsa da AOP bu modele izin vermez.
Konuyu net bir örnek üzerinden anlamaya çalışalım. Klasik müşteri – sipariş örneğini düşünelim. Örneğin müşterilerimizi ve siparişleri tutan iki ayrı sınıf modellediğimizi kabul edelim. Veri bütünlüğü (data integrity) problemi olarak bilindiği üzere bir müşterinin silinmesi ancak hiç siparişi olmayınca mümkündür. Yani şayet bir müşterinin bekleyen bir siparişi varsa ve biz müşteriyi silersek, siparişi gerçekleştiremeyiz çünkü müşterinin iletişim bilgilerini kaybederiz.
Bu durumda aslında müşteri silme fonksiyonu, müşteri sınıfının bir üyesiyken sipariş sınıfının kontrol etmesi gereken bir durum oluşur. Yani müşterinin silme fonksiyonu, sipariş olmadığında çalışabilmektedir.
Bu durum üç sonuç doğurmaktadır:
- Müşteri sınıfı siparişin olup olmadığını kontrol işlemini gerçekleştirememektedir ve tasarım itibariyle kendi fonksiyonunu kendi başına yapamaz. Bu bir tasarım zaafıdır.
- Müşteri sınıfı benzer şekillerde diğer veri bütünlüğü (data integrity) kurallarını da bilemek zoruna kalır. Bu da programlama açısından güçlükler doğurur.
- Müşteri sınıfının yeniden kullanılabilirliği (code reusability) kaybedilir çünkü artık müşteri sınıfı tek başına vâr olamaz. Varlığı sipariş sınıfına bağlıdır. Yani aynı sınıf başka bir projede kullanıldığında sipariş sınıfının da kullanılması gerekir.
Yukarıdaki problemlere çözüm olarak bu veri bütünlüğü kontrolünün sipariş sınıfına konması da birşey değiştirmez çünkü bu durumda aynı problemler sipariş sınıfında tezahür eder.
AOP’nin sağladıkları
AOP yazılım geliştirme yaklaşımlarında son nesil olarak kabul edilebilir. Daha önceki fonksiyonel programlama yaklaşımlarında problem fonksiyonel elemanlara bölünerek her eleman için bir fonksiyon yazılması yoluna gidilmekteydi. Nesne yönelimli yaklaşım biraz daha ileri giderek problemi veri anlamında bütünlük arz eden nesnelerle modelledi. Son olarak bağlam yönelimli programlama (aop) ise bir adım daha ileri giderek noktakesim (pointcut) , birleşme noktası (joinpoint) ve tavsiye (advise) eklentilerinde bulunuyor. Bu terimlerin detaylarını üzerlerine tıklayarak okuyabilirsiniz.