ilgiye yonelik program lama aspectj hduzgun

27
1 LGYE YÖNELK PROGRAMLAMA VE ASPECTJ (ASPECT ORENTED PROGRAMMING AND ASPECTJ) Hikmet DÜZGÜN Hacettepe Üniversitesi Bilgisayar Mühendisli.i Bölümü www.javadili.com

Upload: wwwjavadilicom

Post on 08-Jun-2015

166 views

Category:

Documents


2 download

DESCRIPTION

Ilgiye Yonelik Programlama

TRANSCRIPT

Page 1: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

1

İLGİYE YÖNELİK PROGRAMLAMA VE ASPECTJ

(ASPECT ORİENTED PROGRAMMING AND ASPECTJ)

Hikmet DÜZGÜN Hacettepe Üniversitesi Bilgisayar Mühendisliği

Bölümü

www.

java

dili.

com

Page 2: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

2

İÇİNDEKİLER 1. GİRİŞ ………………………………………………………………………………….. 3

2. AOP MANTIĞINA GİRİŞ VE TEMEL KAVRAMLAR……………………………….. 4

3. BIRLESME NOKTALARI (JOIN POINTS) VE BIRLESIM NOKTA KÜMELERİ

(POINTCUTS) ……………………………………………………………………………… 5

4. DOKUMA (WEAVING) …………………………………………………………………... 6

5. ASPECTJ …………………………………………………………………………………… 6

5.1. ASPECTJ HAKKINDA ……………………………………………………………… 6

5.1.1. DINAMIK BIRLESME NOKTASI MODELI (DYNAMIC JOIN POINT

MODEL) ………………………………………………………………………… 8

5.1.2. BIRLESIM NOKTA KÜMELERI (POINTCUTS) …………………………… 8

5.1.3. TAVSİYE-YORDAM (ADVICE) …………………………………………… ...10

5.1.4. DAHİLİ-TÜR TANIMLARI (INTER-TYPE DECLARATIONS) …………...11

5.1.5. İLGİLER (ASPECTS) …………………………………………………………...12

5.2. GELISTIRME PLATFORMU (UYGULAMALI TANITIM) ……………………..13

6. AOP VE DIGER PROGRAMLAMA MODELLERI ……………………………………26

7. AOP PROBLEMLERI ……………………………………………………………………..26

8. KAYNAKÇA ……………………………………………………………………………….27

www.

java

dili.

com

Page 3: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

3

GİRİŞ

Bu belgede, AOP mantığına basit bir giriş yapılacak, bir JAVA gerçekleştirimi olan AspectJ ve uygulamasına yönelik özet bilgi verilecektir. AOP, geleneksel programlama dillerinin karşılaştıkları özel sorunlara (crosscutting concerns – belge içerisinde ayrıntılı bir şekilde değinilecek ) kolay çözümler getirememeleri nedeniyle ortaya çıkmıştır. AOP geçmişi tüm dünyada çok eskilere kadar dayanmasına rağmen çok fazla ilgi görmemesi nedeniyle yavaş bir gelişme göstermiş ve çok fazla kullanımı olmamıştır. Her bilgisayar mühendisi ya da programcısınıngelecekte öğrenmek için takvimine koyduğu ama biçoğunun zaman ayırmadığı ya da ayıramadığı bir gerçektir. Yine de her geçen gün, gerçekleştirilen uygulamaların büyümesi dolayısıyla bu tür sorunlarla daha fazla karşılaşılması nedeniyle önemi, dolayısıyla da kullanımı artmaktadır. En fazla AOP’ye ilgi uygulama sunucuları alanında olmakta, hatta JBoss 4.0 uygulama sunucusunda ağırlıklı olarak AOP kullanılmıştır. AspectJ, AOP mantığını taşıyan bir JAVA gerçekleştirimidir. Eclipse projesi kapsamında yürütülen projelerden biridir ve gerekli bir takım eklemelerin yapılmasıyla Eclipse platformu üzerinde kodlanıpçalıştırılabilir. Crosscutting sorunlara etkili çözümler getirmesi, debugging imkanı vermesi ve JAVA desteği gibi durumlar sayesinde diğer AOP gerçekleştirimlerine göre daha yaygın bir kullanımı olmuştur. Bu nedenle en bilinen AOP gerçekleştirimidir. Bu dökümanda, AspectJ’ye kısa bir giriş yapılacak, basit örnekler üzerinden ilgili kavram ve yapılar anlatılacak, Eclipse platformu üzerinde küçük bir kodun yazılıpçalıştırılması ekran görüntüleriyle anlatılarak geliştirme platformu hakkında bilgi verilecek, en son da AspectJ’nin karşılaştığı problemlere değinilecektir.

www.

java

dili.

com

Page 4: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

4

AOP MANTIGINA GIRIS VE TEMEL KAVRAMLAR

Aspect-oriented programming(AOP) diğer bir adıyla aspect-oriented software development(AOSD), bir programı mümkün olduğunca farklı özellikler gösteren parçalara bölmeyi hedefleyen bir yaklaşımdır. Türkçeye "ilgiye yönelik programlama, bağlam yönelimli programlama ya da kesit yönelimli programlama" diye de çevrilebilir fakat anlatım kolaylığı açısından metin içerisinde AOP olarak yer alacaktır. AOP, daha çok modulasyon ve sarma(encapsulation-ayrıntıyı kullanıcıdan basit bir arayüz ile saklama) konuları üzerinde durur. Nesneye yönelik programlama da sarma(encapsulation) üzerinde odaklanmasına rağmen kimi durumlarda(crosscutting concerns) yeterli olmamaktadır. Loglama(log oluşturma) bu tür durumlara örnek olarak verilebilir çünkü; loglama stratejisi sistemdeki loglanmış her bir parçayı etkiler. Bu nedenledir ki loglama, tüm loglanmış sınıf, yordam ve prosedürü enine keser yani program içerisinde birçok kez aynıişlevi yapmak maksadıyla tekrarlanır. AOP uygulaması bu tür durumların üstesinden gelmek üzere aspect(ilgi) diye adlandırılan bir yapı tanımlar. İlgi, ilgi(aspect) yapıda bulunmayan kod(base code) davranışları üzerinde değişiklik yapabilir. Bunu da birleşme noktaları (join points) üzerinde ek davranışlar belirleme yoluyla gerçekleştirir. Cross-cutting concerns diğer bir deyişle aspect (ilgi), program içersinde defalarca tekrar eden birbirinden bağımsız modüllerce varolan program parçacıkları olarak da görülebilir. Örneğin, bir hesaptan başka bir hesaba para transferi yapacak basit bir yordama sahip bir banka uygulamasıdüşünelim : void transfer(Hesap hesaptan, Hesap hesaba, int miktar) { if (hesaptan.getBakiye() < miktar) { throw new YetersizBakiyeException(); }

hesaptan.dus(miktar); hesaba.yatir(miktar); }

Fakat bu tarz bir uygulamanın gerçek hayatta yukarıdaki kadar kolay bir yordamla yapılamayacağı açıktır. Öncelikle hesap sahip sahibinin böyle bir işlevi yerine getirmek için yetkisinin olup olmadığının kontrol edilmesi, işlem anında doğabilicek herhangi bir sorun nedeniyle sistemde karışıklık yaşamamak maksadıyla işlemin database transaction arasına alınması ve loglanması gerekir. Bütün bu kaygıları (concerns) taşıyan basit bir uygulama aşağıdaki gibi düşünülebilir : void transfer(Hesap hesaptan, Hesap hesaba, int miktar) { if (!getKullanıcı().gerçekleştirebilir(İŞ_TRANSFER)) {

throw new GüvenlikException(); }

if (hesaptan.getBalance() < amount) { throw new YetersizBakiyeException();

}Transaction tx = database.newTransaction();

try { hesaptan.dus(miktar); hesaba.yatir(miktar); tx.üstlen(); systemLog.logİşlem(İŞ_TRANSFER, hesaptan, hesabat, miktar);

}catch(Exception e) { tx.geriSar();

}} www.

java

dili.

com

Page 5: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

5

Böylelikle kod ilk görünümünden dolayısıyla da basit ve anlaşılır halinden fazlasıyla uzaklaşmış olur. Birçok yeni durum (concern) koda gömülmek durumunda kalır. Bu da yordamın üstlenmesi gereken asılişten yani fonksiyonundan görünürde uzaklaşmasına neden olur. Bu nedenle, database transactions, güvenlik ve loglama işlemleri yaptıkları bu etkiler nedeniyle cross-cutting concerns’e örnek olarak verilebilirler. Diyelim ki sistemin güvenlik yönetiminde değişiklik yapılması gerekiyor. Bu durumda güvenliğin ele alındığı tüm kod parçacıklarının yeni duruma göre uyarlanması gerekir. Tüm sisteme yayılmış bir durum üzerinde günleme yapılmasının yüksek bir maliyete sahip olduğu gözden kaçamayacak derecede belirgindir. Anlaşılacağı üzere, ilgilerin (cross-cutting concerns) ele alınışı sistem temelinde yer aldığı düşünülen durumların ele alınışı kadar kolay degildir. Bu nedenledir ki AOP, bu tür ilgilerin çözümüne ilişkin birbirinden bağımsız, aspect (ilgi) olarak adlandırılan yapılar tanımlar. Neredeyse tüm AOP dillerinde, bir aspect diğer programlama dillerinde yer alan yordam benzeri bir yapıya sahip advice (tavsiyeyordam)’lar ve bu tavsiyeyordamların dokuyacağı (weave) bir dizi join points (birleşme noktaları)içerir.

BIRLESME NOKTALARI(JOIN POINTS) VE BIRLESIM NOKTA KÜMELERI(POINTCUTS) Temelde, bir ilginin ana (base) kodla etkileşimi Join Point Model (JPM – Birleşme NoktasıModeli) olarak tanımlanır. Bir JPM üç şey tanımlar: - Ilgi nerelerde uygulanır. Buralar genelde join points (birleşim noktaları) olarak bilinir. - Çoklu birleşim noktalarını belirlemek için bir yol. Pointcuts (birleşim nokta kümeleri) olarak da bilinir. Birleşim nokta kümeleri, sistemdeki tüm birleşim noktalarından bir alt kümeyi seçmek maksadıyla yapılan sorgular olarak da düşünülebilir. - Birleşim noktaları üzerinde bir tür davranışa etki yöntemi. AspectJ dilinde advice (tavsiyeyordam) olarak da bilinir. AspectJ programlama dilindeki JPM kapmanında düşünülen birleşim noktaları, bir programın çalışmasısürecinde oldukça iyi tanımlanmış noktalardır. Bunlar: method çalışması (method execution), bir nesneye değer atama (instantiation of an object) ve aykırı durum fırlatma ( throwing an exception). Görüleceğiüzere, belirtilen birleşim noktaları ancak program çalışması esnasında farkedilebilecek durumlardır. Bu nedenle AspectJ programlama dilinde, birleşim noktaları kümesi ve önerimethod (advice) JPM dynamic join point model (dinamik birleşim noktası modeli) olarak da bilinir. Birleşme noktaları kümesi program üzerinde yapılan bir sorgu sonucu belirlenir. Örnek bir birleşim nokta kümesi aşağıda gösterilmiştir:

pointcut set() : execution(* *.set*(..) ) && this(Nokta); Nokta tipinde bir nesne çalışma aşamasında (execute) ise, “set” ile başlayan çalışma (execution) durumunda olan tüm yordamlar bu birleşim nokta kümesinde belirlenir. Advice (tavsiyeyordam)’lar JAVA programlama dilindeki yordamlara benzer bir şekilde belirlenirler, fakat onlar gibi dışarıdan (explicitly) çağrılamazlar. Ancak, kendilerine iliştirilen birleşim nokta kümesi doğru (true) döndüğü taktirde kendiliğinden çağrılırlar (implicitly). Örneğin; after() : set() { Görüntüle.güncelle(); }

Yukaridaki koda göre, ancak set() birleşim nokta kümesi true olduktan sonra tavsiye-yordam gövdesi işletilir. ww

w.ja

vadi

li.co

m

Page 6: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

6

AspectJ’de kullanılan bir diğer JPM de inter-type declarions (dahili-tür tanımları) dır. Bu mekanizma, bir ilginin herhangi bir sınıfa ya da nesneye ekstra tanımlar katmasını sağlar. Bu kavram açık sınıf olarak da bilinir. Örnek bir dahili-tür tanımı aşağıdaki gibidir : aspect MisafirKabul {

Nokta.misafirKabulEt(Misafir m) { m.ziyaretEt(this);

}}

Bu kod parçacığı, Nokta sınıfına misafirKabulEt yordamını ekler. • Birleşme noktalarının hepsi non-anonymous türdendir. • Birleşim nokta kümeleri sınıf ya da arayüz (interface) adlarıdır. • Gövde tanımlarının türe eklenmesiyle birleşim nokta kümelerine etki edilebilir.

DOKUMA(WEAVING) Dokuma, tavsiyeyordamı belirtilen birleşme noktalarına uygulama olarak düşünülebilir. Orjinal AOP tanımında, Kiczales ve takımı dokuma için aşağıdaki ihtimalleri sıralamışlardır :

• Bir kaynak ön işlemci (preprocessor) • İkil kütükleri (binary files) yamayacak bir son işlemci (post processor) • Dokunmuş ikil kütükleri tanıyan bir AOP derleyici • Yükleme zamanı dokuma ( örneğin, JAVA’ya göre, ilgili tavsiyeyordamın JAVA’da sınıflarınJVM’e yüklendiği gibi dokunması )• Çalışma zamanı dokuma ( çalışma zamanında her bir birleşme noktasının yakalanması ve ilgili tavsiyeyordamın çalıştırılması )

İlk iki seçenek geliştirme işlemini zorlaştırırken son ikisi de programın çalışmasını yavaşlatır. Ayrıca son seçenek, aspect (ilgi)tanıyan bir çalışma ortamına (JVM gibi) ihtiyaç duyar. Son seçenek dışında tanımlanan tüm seçenekler kod üzerinden herhangi bir noktada değişikliğe yol açarlar. Yükleme zamanı dokumanın ardından derlenmiş JAVA ikil kütükleri içerisinde dokunmuş tavsiyeyordam parçacıkları bulunur. Birçok programcı bunu AOP’nin bir sakıncası olarak görür. Başka bir yöntem ise varolan kod üzerinde herhangi bir değişiklik yapmak yerine, sınıflara ek alt sınıflar yaratma yani deploy-time weaving (yerleştirme zamanı dokuma)’dir. Bu yöntemle varolan sınıflara ait yordamlar yaratılan alt sınıflarca override edilir. Bu şekilde önceki kod değişmeden kaldığından hata ayıklayıcı (debugger) vb. araçlar kullanılmaya devam edilir.

ASPECTJ AspectJ Hakkında AspectJ, kullanımı oldukça kolay, JAVA platform uyumlu bir AOP JAVA gerçekleştirimidir. Crosscutting sorunlar için kolay bir modülarizasyon imkanı sunmakla birlikte, hata kontrolü ve ele alınışı,senkronizasyon, performans iyileştirmeleri, loglama ve hata ayıklama gibi durumlarda da oldukça iddialıdır. AspectJ gerçekleştiriminin kolay anlatımını sağlamak üzere bir örnek üzerinden gitmenin daha mantıklıolacağı inancındayım. Bu maksatla, AspectJ gerçekleştirim özelliklerini vermek üzere bir Şekil Düzenleme Sistemi kullanılacaktır. ww

w.ja

vadi

li.co

m

Page 7: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

7

Bir şekil bir veya daha fazla nokta ya da doğrudan oluşur. Şekil sınıfı factory hizmetini sağlayacak şekilde düzenlenmiştir. Bu sistem için UML gösterimi aşağıdaki gibidir.

AOP oluşmasındaki ana neden, geleneksel programlamlama dillerinde kimi sorunların (concerns) kolaylıkla ele alınamayışı ya da modüle edilememisidir. Örneğin bir program içerisinde ele alınmasıgereken güvenlik kısıtlarını düşündüğümüzde, zamanla bu kısıtların değişebileceği, genişletilebileceği ya da programın farklı kesimlerinde de kullanım ihtiyacı doğuracağı görülebilir. Fakat, güvenlik kısıtlarınınesneye yönelik programlama dilleri gibi geleneksel programlama dillerinde birim modüller (nesneye yönelik programlamada sınıf) haline getirmenin mümkün olmaması nedeniyle programın ihtiyaç duyulan her yerinde bu kısıtların tanımlanması gerekir. Bu nedenle güvenlik, loglama gibi durumların geleneksel programlama dillerinde kontrolü oldukça zor olmakla birlikte hataya da fazlasıyla açıktır. Güvenlik gibi sorunların nesneye yönelik programlamada sınıflar gibi modüle edilememesinin başlıca nedeni sistematik bir şekilde tanımlanamamaları ile program boyunca yayılmış olmaları ve de diğer sınıfları enine kesmeleridir (cross-cut). Bu yüzden sınıflar gibi tekrar kullanılamazlar(resuable) ve kalıtılamazlar(inheritance). Kısacası, bu tür sorunların geleneksel programlama dillerince ele alınmalarıprogramlar için oldukça büyük bir yüktür. AOP, nesneye yönelik programlamanın genel sorunları modüle ettiği yönteme(sınıflar) benzer bir şekilde ilgileri (cross-cutting concerns) modüle etmeye olanak veren bir programlama mantığıdır. AspectJ de AOP mantığını gerçekleştiren bir JAVA gerçekleştirimidir. AspectJ’nin javaya kattığı tek kavram birleşme noktası (join point) kavramıdır. Bunun dışında birleşim nokta kümeleri(pointcuts), tavsiyeyordam(advice), dahili-tür tanımlar (inter-type declarations) ve ilgi(aspect) gibi yapıları da JAVA ya dahil etmiştir. Birleşim nokta kümeleri ve tavsiyeyordamlar program işleyişini dinamik olarak etkilerken dahili-tür tanımlar statik olarak sınıf hiyerarşisine etkide bulunurlar. İlgiler ise bu yapıları sarmalamak (encapsulate) maksadıyla kullanılırlar. Bir birleşme noktası program akışı boyunca iyi tanımlanmış (well-defined) bir noktadır. Birleşim nokta kümesi ise birleşim noktalarından seçmeler yaparak oluşturulmuş bir kümeyi ifade eder. Tavsiyeyordam,herhangi bir birleşme noktasına gelindiğinde çalıştırılan kod parçacığıdır. Bunlar AspectJ nin dinamik kesimlerini oluşturur.

Görüntüle

Sekil <<factory>> +yaratNokta() +yaratDogru()

SekilEleman +ataXY() +ciz()

Nokta -x: int -y: int

Dogru -n1: Nokta -n2: Nokta

1 n

SekilDuzenleme örneği için UML gösterimi

www.

java

dili.

com

Page 8: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

8

Ayrıca AspectJ, programın statik yapısı üzerinde(daha çok sınıflara ait değişkenler ve yordamlar ile sınıflar arası ilişkiler konu edilir) değişiklik yapabilecek birçok farklı dahili-tür tanım içerir. AspectJ’de ilgiler ise JAVA’daki sınıf tanımları gibi AspectJ için birim modüller olarak düşünülür. Bu modüller ilgilerin(cross-cutting concerns) modüle edilmesi maksadıyla yaratılmışlardır, fakat sınıflardan farklı olarak birleşme noktaları, birleşim nokta kümeleri ve dahili-tür tanımlar da içerebilirler. Birazdan anlatacağım kesimde ilkin birleşme noktalarına ardından bu noktalardan bir ya da birkaçınınbiraraya gelerek oluşturduğu birleşim nokta kümelerine, bu nokta kümelerine rastlandığı durumlarda çalıştırılan kod parçacıkları olan tavsiyeyordamlara göz atacağız. Daha sonra birleşim nokta kümeleriyle tavsiyeyordamların ilgi oluşturmak üzere nasıl bir araya geldiğini inceleyeceğiz. En son olarak da tanımların programın statik yapısı içinde yer alan sınıflar içindeki ilgileri (cross-cutting concerns) ele aldığına değineceğiz.

Dinamik Birleşme Noktasi Modeli(Dynamic Join Point Model) Birleşme noktası modeli (JPM), AOP deki kritik elemanlardan biridir. JPM, crosscutting sorunlarındinamik yapısının tanımlanmasını mümkün kılan bir referans çerçeve sağlar. Bu kısımda, bir program çalışması esnasında belirgin olarak tanımlanmış dinamik birleşme noktalarından bahsedilecektir. AspectJ’de kullanılabilecek birleşme noktaları :

� Yordam çağrıldığında � Yordam çalışırken � Yapımcı tetiklendiğinde � Yapımcı çalışırken � Aspect kodu çalışırken � Nesne yapılandırılırken � Sınıf değişkenine erişilirken � Sınıf değişkenine atama yapılırken

AspectJ, birçok birleşme noktası tanımı içerirken burada sadece yordam-çağrımlı birleşme noktası (method call join point) üzerinde durulacaktır. Yordam-çağrımlı birleşme noktası, herhangi bir yordam tarafından çağrılmış bir nesnenin hareketlerini olduğu gibi sarmalar. Bu hareketlere, bir yordam çağrımına ait argümanların alınıp yordamdan dönüş yapılana dek sahip olduğu tüm hareketler dahildir. Çalışma zamanındaki tüm yordam çağrımlarının her biri, aynı yordama ait çağrım olsa bile ayrı bir birleşim noktası olarak ele alınır. Bir yordam çağrımlı birleşme noktası çalışırken, o sırada birden fazla birleşme noktası ( yordam içerisinde oluşmuş ya da yordam gövdesinde başka bir yordam-çağrımı sayesinde meydana gelmiş) çalışıyor olabilir. Bu durumda, arka planda çalışan birleşme noktalarına orjinal yordam-çağrımlı birleşme noktasının dinamik bağlamın(dynamic context) da çalışıyor denir.

Birleşim Nokta Kümeleri ( Pointcuts ) AspectJ’de birleşim nokta kümeleri, program akışı boyunca belli birleşme noktalarının seçilmesi yoluyla oluşturulmuş kümelerdir. Örneğin ; call(void Nokta.ataX(int)) yukaridaki birleşim nokta kümesi, void Nokta.ataX(int) prototipinde( Nokta sınıfına ait ataX (int) yordamı)olan tüm yordam-çağrım birleşme noktalarını seçer. Bir birleşim nokta kümesi, başka birleşim nokta kümelerinin ve( & ), veya( || ), değil ( ! ) durumlarıyla bağlanması yoluyla da oluşturulabilir. Örneğin ; call(void Nokta.ataX(int)) || ww

w.ja

vadi

li.co

m

Page 9: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

9

call(void Nokta.ataY(int)) yukarıdaki örnekte, Nokta.ataX(int) veya Nokta.ataY(int))ye olan her bir yordam-çağrımlı birleşme noktası seçilir. Birleşim nokta kümeleri, farklı türdeki birleşme noktalarını da tanıyabilirler. Örneğin;

call(void SekilEleman.ataXY(int,int)) || call(void Nokta.ataX(int)) || call(void Nokta.ataY(int)) || call(void Dogru.ataN1(Nokta)) || call(void Dogru.ataN2(Nokta)); yukarıdaki kod kesimi ile 5 yordam çağrımından herhangi birine yapılan çağrım olan birleşme noktalarınınher biri seçilir. Tanımladığımız örnek sisteme göre yukarıdaki kod kesimi ile bir SekilElement hareketi gerçekleştiğinde tüm birleşme noktalarını yakalanır (capture). Bu crosscutting sorunların tespiti açısından güzel bir yol olmasına rağmen kullanımı ve kontrolü zordur. Bu durumu aşmak için AspectJ, programcıların birleşim nokta kümelerine istedikleri ismi vermelerine imkan tanır. Örneğin aşağıdaki kod ile isimlendirilmiş bir birleşim nokta kümesi oluşturulur : pointcut tasi() : call(void SekilEleman.ataXY(int,int)) ||

call(void Nokta.ataX(int)) || call(void Nokta.ataY(int)) || call(void Dogru.ataN1(Nokta)) || call(void Dogru.ataN2(Nokta));

Bu tanımın görünür (visible) olduğu bir an programcının bahsedilen karmaşık birleşim kümesini yakalamak için tasi() kullanması yeterlidir. Yukarıdaki tüm örneklerde, yordamlara ait tam yapı verilerek birleşim nokta kümelerinin oluşumu sağlanmıştır. Bu yöntem isim-bazlı enine kesim (name-based crosscutting) olarak da bilinir. AspectJ programcılara, yordamın tam bir prototipini belirtmeleri yerine sadece yordama ilişkin belli bir özelliğibelli birtakım özel simgeler(wildcards) kullanarak ifade etmelerine olanak verir. Buna özellik-bazlı enine kesim (property-based crosscutting) de denir. Örneğin, birleşim nokta kümesi call(void Sekil.yarat*(..)) Sekil sınıfına ait void geri dönüş tipine sahip adı yarat ile başlayan, aldığı parametrelerden bağımsız tüm yordam çağrımlarını seçer. Bu tanım ile, örnek sistemimiz içindeki yaratNokta ve yaratDogru factory yordamları seçilir. Birleşim nokta kümesi call(public * Sekil.* (..))

Sekil sınıfının public türde olan her bir yordamına yapılan yordam çağrımlarını seçer. AspectJ de kullanılabilecek tek özellik (property) özel simgeler (wildcards) değildir. Diğer bir birleşim nokta kümesi, cflow, diğer birleşme noktalarının dinamik bağlamında (dynamic context) ortaya çıkan birleşme noktalarını belirtir. Bu sayede, cflow(tasi()) ww

w.ja

vadi

li.co

m

Page 10: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

10

tasi() ile seçilen birleşme noktalarının dinamik bağlamında ortaya çıkan birleşme noktalarını seçer. Yani, bu birleşim nokta kümesi, tasi yordamının çağrılmasından bitimine kadar ki süreçte ortaya çıkan her bir birleşme noktasını seçer.

Tavsiyeyordam ( Advice ) Yukarıda belirtildiği üzere birleşim nokta kümeleri, bir dizi birleşme noktasını seçmek için kullanılır ama bu noktalar üzerinde ne gibi işlemler yapılacağına ya da bu noktaların ne şekilde kullanılacağına dair bir bilgi içermezler. AspectJ’de bu görev tavsiyeyordam (advice)’lara verilmiştir. AspectJ’de bir çok tavsiyeyordam yer alır. Bunlardan before, bir birleşme noktasının işletimine geçilmeden önce ele alınması istenen durumların tanımlandığı tavsiyeyordam’dır. Örneğin, bir yordam-çağrımlıbirleşme noktası üzerinde tanımlı tavsiyeyordam gerçek yordam işletime alınmadan hemen önce (gerçek yordama ait parametre geçişinin hemen ardından) işletilir. before() : tasi() { System.out.println(“taşınmadan hemen önce”); }

After tavsiyeyordamı ise programın, birleşme noktasını işletmesinin hemen ardından işletilir. Örneğin, bir yordam-çağrımlı birleşme noktasıyla tanımlanmış bir tavsiyeyordam, yordamın işletiminin ardından kontrol çağıran yordama geçmeden hemen önce işletilir. Java programları bir birleşme noktasından normal olarak ya da aykırı durum fırlatarak çıkabileceklerinden AspectJ’de üç tip after tavsiyeyordamı bulunur. Bunlar : after returning, after throwing, after(normal sonlanma ya da aykırı durum oluşumundan herhangi birinden sonra). after () returning : tasi () { System.out.println(« başarılı bir taşımanın ardından ») ; }

Birleşim Nokta Kümelerinde İçerik Gösterimi (Context Exposing) Birleşim nokta kümeleri, birleşme noktalarını seçmek dışında birleşme noktalarındaki işletim içeriğini (execution context) de gösterebilirler. Birleşim nokta kümeleri tarafından ortaya çıkarılan (gösterilen) değerler, tavsiyeyordam tanımlarında kullanılabilirler. Bir tavsiyeyordam tanımı, Java’daki yordamlarda olduğu gibi bir parametre listesine sahiptir. Bu parametreler, tavsiyeyordam tarafından kullanılacak içerik parçalarına isim vererek gövde kısmında kullanılabilecek şekilde tanımlanmıştır. Örneğin aşağıdaki ; after (SekilEleman se, int x, int y) returning : …BaziBirlesimNoktaKumeleri…{ …BaziGövdeTanimlari… }

tavsiyeyordam, se adında bir SekilEleman ile x ve y adında iki int türünde parametre olmak üzere toplam üç parça exposed context içerir. Tavsiyeyordam gövdesi, aynen Java’daki yordamlarda olduğu gibi parametre kullanımına sahip olduğuiçin tavsiye yordam aşağıdaki şekli alabilir : after (SekilEleman se, int x, int y) returning : …BaziBirlesimNoktaKumeleri…{ System.out.println(se + « belirtilen noktalara taşındı (« + x + », « + y + ») ») ; } ww

w.ja

vadi

li.co

m

Page 11: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

11

Tavsiyeyordama ait birleşim nokta kümesi, argümanlara ait değerleri neşretmek (göstermek - publish) için kullanılır. Üç ilkel birleşim nokta kümesi bu argümanlara ait değerleri göstermek için kullanılabilir : this, target, args. Bu durumda tavsiyeyordamın alacağı şekil aşağıdaki gibi olacaktır. after (SekilEleman se, int x, int y) returning : call(void SekilEleman.ataXY(int, int))

&& target(se) && args(x,y){

System.out.println(se + « belirtilen noktalara taşındı (« + x + », « + y + ») ») ; }

Tavsiyeyordam ataXY yordamından üç değer çıkarır : hedef SekilEleman (se) ve iki int değer x, y. Bunlardan se after tavsiyeyordamının ilk argümanı olurken x ile y son iki argumanı olur. Bu durumda, yukarıdaki tavsiyeyordam, her ataXY yordamının işletiminin ardından SekilEleman se ve yeni x, y koordinatlarını ekrana basar. Bir isimlendirilmiş birleşim nokta kümesi, tavsiyeyordam parçası gibi bir parametre listesine sahip olabilir. Yukarıdaki tavsiyeyordam bu durumda aşağıda gösterildiği gibi de yazılabilir : Pointcut ataXY(SekilEleman se, int x, int y): call(void SekilEleman.ataXY(int, int))

&& target(se) && args(x,y) ;

after (SekilEleman se, int x, int y) returning : ataXY(se,x,y) { System.out.println(se + « belirtilen noktalara taşındı (« + x + », « + y + ») ») ;

}

Dahili-tür Tanımları

Dahili tür tanımları, sınıfları ve sınıf hiyerarşilerini enine kesen tanımlardır. Birden fazla sınıfı enine kesen sınıf özelliği tanımlayabilir ya da sınıflar arası kalıtım ilişkisi üzerinde değişiklik yapabilir. Tavsiye-metodlardan farklı olarak dinamik değil de statik olarak işlev görürler. Hazır bir sınıf hiyerarşisine sahip bir programa, birçok sınıf tarafından paylaşılacak yeni bir yetenek (capability) eklememiz gerektiğini düşünelim. (Örneğin, bu sınıflar bir ata sınıftan türetilmiş olsunlar) Bu durumda Java bir Interface (=Arayüz) tanımlayıp bu yeteneğe ait yordam ya da yordamları bu arayüzün içine gömme yoluyla genişlemeyi sağlar. Böylece bu yeni yeteneğe sahip olacak sınıflar bu arayüzü implement edecek yordamlarla genişletilirler. AspectJ, bu sorunu sadece tek bir yapı oluşturarak, varolan sınıflar üzerinde herhangi bir değişikliğegitmeden, halledebilir. Yeni yeteneğin eklenebilmesi için gereken yordam ve alanları tanımlayıp bunlarıvarolan sınıflar ile ilişkilendirir. Daha önceden varolan bir sınıf olan Nokta sınıfına ait nesneleri üzerindeki değişimleri gözlemek üzere gözlemci rolüne sahip Ekran nesnelerine sahip olmak istediğimizi varsayalım. Nokta nesneleri üzerindeki değişimleri gözleyen Ekran nesnelerinin izini tutan gozlemciler adında Nesne sınıfına ait bir alanı aspect (ilgi) yazarak kodlayabiliriz. aspect NoktaGozlem { private Vector Nokta.gozlemciler = new Vector() ; ……… } ww

w.ja

vadi

li.co

m

Page 12: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

12

gozlemciler alanı private olduğundan sadece NoktaGozlem’den erişilebilir. Bu nedenle, gözlemciler ancak static yordamlar gozlemciEkle, gozlemciCikar yordamlarının aspect (ilgi)’e eklenmesi yoluyla eklenip çıkarılabilirler. aspect NoktaGozlem { private Vector Nokta.gozlemciler = new Vector() ; public static void gozlemciEkle ( Nokta n, Ekran e) { n.gozlemciler.add(e) ; } Public static void gozlemciCikar ( Nokta n, Ekran e) { n.gozlemciler.remove(e) ; } ……… }

Bunların ardından, neyi izlemek istediğimize dair degisiklikler adında bir birleşim nokta kümesi tanımlayabiliriz. after tavsiye-yordam ise bir değişiklik meydana geldiğinde ne yapacağımızı tanımlamak için kullanılabilir. aspect NoktaGozlem { private Vector Nokta.gozlemciler = new Vector() ; public static void gozlemciEkle ( Nokta n, Ekran e) { n.gozlemciler.add(e) ; } Public static void gozlemciCikar ( Nokta n, Ekran e) { n.gozlemciler.remove(e) ; }

pointcut degisiklikler(Nokta n) : target(n) && call(void Nokta.ata*.(int)) ; after(Nokta n) : degisiklikler(n) { Iterator iter = n.gozlemciler.iterator() ; While(iter.hasNext()) { gozlemciGoruntule(n, (Ekran) iter.next()) ; } static void gozlemciGoruntule(Nokta n, Ekran e) { e.goruntule(n) ; }

}

Görüldüğü üzere, bu yeni yeteneğin programa katılması esnasında ne Nokta sınıfı ne de Ekran sınıfıkodlarında herhangi bir değişikliğe gerek duyulmadı.

Aspects (İlgiler) İlgiler, birleşme noktalar, birleşim nokta kümeleri ve dahili-tür tanımlarını bir modül olarak sarmalayan, Java’daki sınıf vari bir yapıdır. Sınıflar gibi yordamlar, alanlar ve ilk değer atayıcılar (initializers) içerebilir. Aspect’lere de sınıflar gibi ilk değer atanabilir fakat bunun nasıl yapılacağı kontrol altındadır ve bu nedenle Java’nın new formatı ile aspect nesneleri (instance) yaratılamaz. Her bir aspect aslında bir Singleton’dur ve sadece bir nesne yaratılır. Bu nedenle tavsiye-yordam aspect’in non-static alanlarını kullanabilir.

www.

java

dili.

com

Page 13: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

13

aspect Loglama { OutputStream logStream = System.err ;

before() : tasi() { logStream.println(« taşınmak üzere ») ; } }

GELISTIRME PLATFORMU (UYGULAMALI TANITIM) Aspectj günümüzde Eclipse projelerinden biri olarak geliştirilmeye devam ettiğinden geliştirme platformu olarak Eclipse anlatılacaktır. Eclipse üzerinde uygulama geliştirmek için öncelikle http://www.eclipse.org/aspectj/ adresinden aspectj-xxx.jar çalıştırılabilir kütüğü indirilerek çalıştırılmalıdır. Bu dosya çalıştırılabilir bir GUI arayüzüne sahip olduğundan yüklemesi oldukça kolaydır. Program kurulumuna ait bir ekran görüntüsü aşağıdadır.

Kurulumun tamamlanmasının ardından, kurulum dizini/lib (Örneğin ; C:\aspectj1.2\lib)’in altında yer alan aspectjrt.jar kütüğü classpath’e eklenmelidir. Bu kütük yazılan sınıf ve aspect’lerin ajc derleyicisi tarafından derlenmesi ve ajc tarafından derlenmiş kütüklerin çalıştırılması için gerekli olan sınıfları içerir. aspectjrt.jar kütüğünü classpath’e eklemek için kullanılabilecek yollardan en uygunu bu kütüğüjdk/jre/lib/ext dizininin altına kopyalamaktır. Kurulum ve program geliştirimine ait dökümantasyona (i.e.api, userguide) yine AspectJ kurulum dizini altında yer alan /doc dizini aracılığıyla erişilebilir. Ayrıca, kurulum dizini altında birçok örnek uygulama programı da yer aldığından bunların incelenmesi aracılığıyla program geliştirimi kolaylaştırılabilir. ww

w.ja

vadi

li.co

m

Page 14: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

14

Yukarıda belirtilen işlemlerin tamanlanmasının ardından Eclipse’de kod yazılıp çalıştırılabilecektir. Bu anlamda örnek bir uygulama (Aspect (ilgi) kullanılarak yordam takibi) ileride ekran görüntüleriyle desteklenerek anlatılacaktır. İlgi Kullanılarak Yordam Takibi Takip (tracing) özelliğine sahip bir sınıf yazmak oldukça kolaydır : birkaç fonksiyon, izlemeyi açıpkapatacak bir boolean işaret, output stream için bir seçenek ve belki de output formatını ayarlamak için programın öngördüğü bir kod kesimi. Bunlar takip sınıflarının sahip olması gereken temel özelliklerdir. Yalnız program gereksinimleri göz önüne alındığında, takip oldukça karmaşık bir yapıya da bürünebilir. Aslında takip geliştirimi işin kolay yanını oluşturur. Takip sınıfları için asıl problem yaratan kesim program içinden uygun zamanlarda takip için etkileşime geçmektir. Bu maksatla yapılan yordam çağrımları özellikle büyük sistemlerde oldukça bunaltıcı olabilmekle beraber sisteme aşırı yük olarak da negatif etki yapar ve çalışma hızını düşürür. Bu nedenle, program satış aşamasına geldiğinde takip sınıflarının sistemden çıkarılma durumu oluşur. Bu durum göz önüne alındığında program geliştiren kişilerin, yordam gövdeleri işletilmeden önce ve işletildikten sonra takip ekleme çıkarma yoluyla yordam çağrımları yapan geçici (ad-hoc) scripting programları kullanmaları oldukça doğaldır. AspectJ, bahsedilen geçici scripting kullanımlarının önüne geçecek ya da kullanımlarını azaltacak bir işlev sağlar. Takip tüm bir sistemi etkilediği göz önüne alınırsa, sistem için bir cross-cutting concern olarak görülebilir, bu durumda bir aspect (ilgi) tarafından sarmalanarak sisteme dahil edilmesi olasıdır. Örnek Uygulama : Örnek uygulama olarak ilk aşamada 4 sınıftan oluşan basit bir şekil uygulaması verilecektir. Bu uygulama ata sınıf olarak Sekil, bu sınıftan türeyen Kare ve Daire sınıfları ile bu sınıflara ait yordamların kullanıldığı main yordamına sahip OrnekMain sınıfını içerecektir. Bu uygulamanın Eclipse platformu üzerinde geliştirimi ve çalıştırılması adım adım verilecektir. Öncelikle Takip adlı bir AspectJ projesi açmakla işe başlıyoruz. Bunun için, File � new � Project yoluyla açılan pencereden AspecjJ Project seçilir. Açılan pencereye ait ekran görüntüsü aşağıdaki gibidir.

www.

java

dili.

com

Page 15: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

15

Project name alanı doldurularak projeye bir isim verilir (örneğimiz için proje adı Takip olacaktır) ve Finish’e basılarak proje oluşturulur. Package Explorer’da Takip başlığı altında proje görüntülenebilir. Takip projesi içinde takip adında bir package yaratılır. Bu işlem için File � new � Package yolu izlenebilir.

www.

java

dili.

com

Page 16: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

16

Bu işlemin ardından açılacak pencere görünümü aşağıda verilmiştir.

Name alanına takip yazıldıktan sonra Finish düğmesine basılarak Takip projesi içinde takip adında bir package oluşturulur. Sekil adındaki ata sınıfı oluşturmak için File � new � class seçeneği kullanılır. Sınıflar aynı yöntemle yaratılacakları için ekran görünümü sadece bu sınıfta verilecektir.

www.

java

dili.

com

Page 17: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

17

Package alanına takip, Name alanına Sekil yazıldıktan sonra Finish düğmesine basılarak Sekil sınıfıyaratılarak takip paketine eklenir. Sekil sınıfının yaratılmasının ardından Eclipse’e ait ekran görüntüsü aşağıdaki gibi olacaktır.

www.

java

dili.

com

Page 18: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

18

Sekil sınıfına ait kod kesimi aşağıdadır :

package takip; /** * Sekil sınıfı bir abstrack sınıf olup, 2 boyutlu şekillere ait genel fonksiyonları içerir */ public abstract class Sekil { /** * Şeklin merkezine ait x ve y koordinatları

*/ protected double x, y;

protected Sekil(double x, double y) { this.x = x; this.y = y; }

/** * x koordinatını döner */ public double getX() { return x; }

/** * y koordinatını döner */ public double getY() { return y; } ww

w.ja

vadi

li.co

m

Page 19: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

19

/** * Parametre olarak gelen şekille bu şekil arasındaki mesafeyi döner */ public double distance(Sekil s) { double dx = Math.abs(s.getX() - x); double dy = Math.abs(s.getY() - y); return Math.sqrt(dx*dx + dy*dy); }

/** * Şeklin çevresini döner. Alt sınıflarda tanımlanmak zorundadır. */ public abstract double cevre();

/** * Şeklin alanını döner. Alt sınıflarda tanımlanmak zorundadır. */ public abstract double alan();

/** * şeklin string gösterimini döner -- basitçe x ve y koordinatlarını

*/ public String toString() {

return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");

}}

Sekil sınıfının alt sınıfları olan Kare ve Daire sınıfları da aynı şekilde projeye dahil edilir. Projenin çalıştırılabilmesi için gerekli bir main () yordamı içeren OrnekMain sınıfının da eklenmesiyle çalıştırılabilir bir Java application hazırlanmış olur. Bu sınıflara ait kod kesimleri aşağıda yer almaktadır. Kare sınıfına ait kod kesimi : package takip; /** * * Kare, Sekil sınıfını kenar özelliğiyle implement eder. cevre ve alan yordamlarını karenin * çevre ve alanını doğru şekilde hesaplayacak şekilde kodlar. * */ public class Kare extends Sekil { protected double k; // kenar

/* * Her türden constructor */ public Kare(double x, double y, double k) { super(x, y); this.k = k; }

public Kare(double x, double y) { this(x, y, 1.0); ww

w.ja

vadi

li.co

m

Page 20: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

20

}

public Kare(double k) { this(0.0, 0.0, k); }

public Kare() { this(0.0, 0.0, 1.0); }

/** * Karenin çevresini döner */ public double cevre() { return 4 * k; }

/** * Karenin alanını döner */ public double alan() { return k*k; }

/** * Bu yordam ata sınıftaki toString yordamını override eder. * Kare ile ilgili spesifik bilgi içerir. */ public String toString() { return ("Karenin kenarı = " + String.valueOf(k) + super.toString()); }}

Daire sınıfına ait kod kesimi : package takip; /** * * Daire, Sekil sınıfını yarıçap özelliğiyle implement eder. cevre ve alan yordamlarını karenin * çevre ve alanını doğru şekilde hesaplayacak şekilde kodlar. * */ public class Daire extends Sekil { protected double r; // yarıçap --> radius

/* * Yapıcılar */ public Daire(double x, double y, double r) { super(x, y); this.r = r; }

public Daire(double x, double y) { this(x, y, 1.0); ww

w.ja

vadi

li.co

m

Page 21: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

21

}

public Daire(double r) { this(0.0, 0.0, r); }

public Daire() { this(0.0, 0.0, 1.0); }

/** * Dairenin çevresini döner */ public double cevre() { return 2 * Math.PI * r; }

/** * Dairenin alanını döner */ public double alan() { return Math.PI * r*r; }

/** * Bu yordam ata sınıftaki toString yordamını override eder. * Daire ile ilgili spesifik bilgi içerir. */ public String toString() { return ("Daire yarıçapı = " + String.valueOf(r) + super.toString()); }}

OrnekMain sınıfına ait kod kesimi : package takip; /** * * Şekilleri test etmek için gereken main() yordamını içeren sınıf**/

public class OrnekMain { public static void main(String[] args) { Daire d1 = new Daire(3.0, 3.0, 2.0); Daire d2 = new Daire(4.0);

Kare k1 = new Kare(1.0, 2.0);

System.out.println("d1.cevre() = " + d1.cevre()); System.out.println("d1.alan() = " + d1.alan());

System.out.println("k1.cevre() = " + k1.cevre()); System.out.println("k1.alan() = " + k1.alan());

System.out.println("d2.mesafe(d1) = " + d2.mesafe(d1)); www.

java

dili.

com

Page 22: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

22

System.out.println("k1.mesafe(d1) = " + k1.mesafe(d1));

System.out.println("k1.toString(): " + k1.toString()); }}

Tanımlanan sınıflara ait yordamların doğru çalışıp çalışmadığını görmek maksadıyla OrnekMain sınıfıçalıştırılır. Projeyi çalıştırmak için Run � Run as � aspectJ/Java application yolu izlenir ve aşağıdaki çıktı elde edilir. d1.cevre() = 12.566370614359172 d1.alan() = 12.566370614359172 k1.cevre() = 4.0 k1.alan() = 1.0 d2.mesafe(d1) = 4.242640687119285 k1.mesafe(d1) = 2.23606797749979 k1.toString(): Karenin kenarı = 1.0 @ (1.0, 2.0) Yukarıda tanımı verilen uygulamaya aspect kullanmadan takip mekanizması eklemek istediğimizde aşağıda kod kesimi verilen AspectsizTakip sınıfına benzer yapıda bir sınıf eklememiz gerekir. AspectsizTakip sınıfına ait kod kesimi : package takip; import java.io.PrintStream; /** * * Bu sınıf bazı temel takip işlevlerine ait mesajlar yazmayı sağlar. * */ public class AspectsizTakip { /** * 3 takip seviyesi bulunur (TAKIPSEVIYESI değerleri): * 0 - Hiçbir mesaj yazılmaz * 1 - Takip mesajları yazılır, fakat girintili yazım yoktur * 2 - Trace messages are printed, fakat girintili yazım vardır

*/ public static int TAKIPSEVIYESI = 0; protected static PrintStream stream = null; protected static int cagirmaDerinligi = 0;

/** * İlk değer atama. */ public static void initStream(PrintStream s) { stream = s; }

/** * "giriyor" şeklinde bir mesaj yazar. Takip edilmek istenen yordamın başında * çağrılması niyetlenmiştir. */ public static void takipGiris(String str) { ww

w.ja

vadi

li.co

m

Page 23: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

23

if (TAKIPSEVIYESI == 0) return; if (TAKIPSEVIYESI == 2) cagirmaDerinligi++; girisYazdir(str); }

/** * "çıkıyor" şeklinde bir mesaj yazar. Takip edilmek istenen yordamın sonunda * çağrılması niyetlenmiştir. */ public static void takipCikis(String str) { if (TAKIPSEVIYESI == 0) return; cikisYazdir(str); if (TAKIPSEVIYESI == 2) cagirmaDerinligi--; }

private static void girisYazdir(String str) { girintiBirak(); stream.println("--> " + str); }

private static void cikisYazdir(String str) { girintiBirak(); stream.println("<-- " + str); }

private static void girintiBirak() { for (int i = 0; i < cagirmaDerinligi; i++) stream.print(" "); }}

Eğer aspect olmasaydı yukarıdaki sınıfla çalışmak zorunda kalınacaktı. Bu durumda takip edilmek istenen tüm yordam ve yapıcıların başında girisYazdir(), sonunda da cikisYazdir() yordamlarını çağırmak ve TAKIPSEVIYESI ile stream’e ilk değer atamalarını yapmak gerekecekti. Ayrıca arada bazı yordamlarıatlama ihtimali de bulunacağından oldukça sağlıksız bir yöntem olduğu açıktır. Bu nedenle takip mekanizmasını aspect kullanarak kodlamak çok daha mantıklıdır. Bu işlevi yerine getirebilecek bir aspect’e ait kod aşağıdadır :

AspectliTakip aspect’ine ait kod kesimi : package takip; /** * Bu sınıf AspectsizTakip sınıfındaki takip yordamları ile uygulama sınıflarındaki * yapıcı ve yordamları birbirine bağlar. * */ aspect AspectliTakip { /** * Uygulama sınıfları.

*/ pointcut benimSinifim(): within(Sekil) || within(Daire) || within(Kare); /** * Bu sınıflardaki yapıcılar. ww

w.ja

vadi

li.co

m

Page 24: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

24

*/ pointcut benimYapicim(): benimSinifim() && execution(new(..)); /** * Bu sınıflardaki yordamlar. */ pointcut benimYordamim(): benimSinifim() && execution(* *(..));

/** * Yapıcılar çalışmadan önce ve çalıştıktan sonra takip mesajlarıyazar. */ before (): benimYapicim() { AspectsizTakip.takipGiris("" + thisJoinPointStaticPart.getSignature()); }

after(): benimYapicim() { AspectsizTakip.takipCikis("" + thisJoinPointStaticPart.getSignature()); }

/** * Yordam gövdeleri çalışmadan önce ve çalıştıktan sonra takip mesajları yazar. */ before (): benimYordamim() { AspectsizTakip.takipGiris("" + thisJoinPointStaticPart.getSignature()); }

after(): benimYordamim() { AspectsizTakip.takipCikis("" + thisJoinPointStaticPart.getSignature()); }

/** * AspectsizTakip aspect'inin çalışması için gereken main fonksiyon. */ public static void main(String[] args) { AspectsizTakip.TAKIPSEVIYESI = 2; AspectsizTakip.initStream(System.err); OrnekMain.main(args); }}

Yukaridaki aspect, yordam çağrımlarında uygun takip mekanizmalarını işletir. Dolayısıyla verilen sınıfhiyerarşisinde çağrılan her yordam ve yapıcı için yordama girişte ve yordamdan çıkışta giriş ya da çıkış mesajları yazdırır. Yordam girişinde ya da çıkışında yazdırılan mesaj çalışan yordama ait signature (imza) dır. İmza statik bir bilgi olduğu için thisJoinPointStaticPart ile erişilebilir. AspectliTakip aspect’i içinde yer alan main() yordamı kullanılarak bu uygulama çalıştırılır. Uygulamayıçalıştırmak için AspectliTakip aspect’i aktif iken Run � Run as � aspectJ/Java application seçilir. Çalışma sonucu elde edilen çıktı aşağıdadır. ww

w.ja

vadi

li.co

m

Page 25: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

25

--> takip.Sekil(double, double) <-- takip.Sekil(double, double) --> takip.Daire(double, double, double) d1.cevre() = 12.566370614359172

d1.alan() = 12.566370614359172 k1.cevre() = 4.0 k1.alan() = 1.0 d2.mesafe(d1) = 4.242640687119285 <-- takip.Daire(double, double, double)

--> takip.Sekil(double, double) <-- takip.Sekil(double, double) --> takip.Daire(double, double, double) <-- takip.Daire(double, double, double) --> takip.Daire(double) <-- takip.Daire(double) --> takip.Sekil(double, double) <-- takip.Sekil(double, double) --> takip.Kare(double, double, double) <-- takip.Kare(double, double, double) --> takip.Kare(double, double) <-- takip.Kare(double, double) --> double takip.Daire.cevre() <-- double takip.Daire.cevre()k1.mesafe(d1) = 2.23606797749979

k1.toString(): Karenin kenarı = 1.0 @ (1.0, 2.0) --> double takip.Daire.alan() <-- double takip.Daire.alan() --> double takip.Kare.cevre() <-- double takip.Kare.cevre() --> double takip.Kare.alan() <-- double takip.Kare.alan() --> double takip.Sekil.mesafe(Sekil)

--> double takip.Sekil.getX() <-- double takip.Sekil.getX() --> double takip.Sekil.getY() <-- double takip.Sekil.getY()

<-- double takip.Sekil.mesafe(Sekil) --> double takip.Sekil.mesafe(Sekil)

--> double takip.Sekil.getX() <-- double takip.Sekil.getX() --> double takip.Sekil.getY() <-- double takip.Sekil.getY()

<-- double takip.Sekil.mesafe(Sekil) --> String takip.Kare.toString()

--> String takip.Sekil.toString() <-- String takip.Sekil.toString()

<-- String takip.Kare.toString()

www.

java

dili.

com

Page 26: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

26

İşletim sonunda elde edilen ekran görüntüsü aşağıdadır :

AOP VE DİĞER PROGRAMLAMA MODELLERİ

AOP, nesneye yönelik programlama (OOP)’nın eksiklerinin göz önüne alınmasıyla oluşturulmuştur ve meta-object protocols’e benzer bir fonksiyona sahiptir. Aspect (ilgi) subject, mixins ve delegation gibi programlama konularıyla yakından alakalıdır. Matematiksel olarak, ilgiler herhangi bir programlama modeli için bir ikinci düzen formu oluştururlar. Genel programlama modelleri basit fonksiyonlar ve mesajlarla ilgili muhakeme imkanı verirken, AOP tüm bunların kümesi üzerinde birleşim nokta kümesi aracılığıyla muhakeme imkanı verir. Bu nedenle, istendiğitaktirde AOP, bağımsız bir programlama modelinden ziyade güçlü bir gerçekleştirim (extension) olarak da görülebilir. AOP PROBLEMLERİ

AOP’nın en büyük sorunlarından biri hata ayıklama (debugging) dir. Bunun nedeni de program kodu içersinde AOP kodunun ayrı görünmesine rağmen çalışma aşamasında bu ayrımın yok olmasıdır. Bu durumda çalışma sırasında, ilgi dokuma (concern weaving), hangi ilginin baskın olacağı belirtilmezse tahmin edilemeyebilir. Tasarımcılar kodun ayrılması konusunda her nekadar alternatif çözüm yolları da aramış olsalar, bunların hiçbiri programcıların birden fazla birleşme noktasına bir tek tanımlayıcı cümlecik ile erişmelerini sağlayamamıştır. Diğer bir sorun ise AOP geliştirimlerinde istenmeyen birleşme noktalarının da özel işaretler (wildcards) yoluyla birleşim nokta kümelerine dahil edilmesidir. Diyelim ki, bir programcı belli bir karakter kümesi kullanarak bu karakter kümesiyle başlayan yordamlara ilişkin birleşme noktalarını bir birleşim nokta kümesinde toplamış olsun. Belli bir süre sonra programa unutarak bu karakter kümesiyle başlayan başka bir yordam eklediğinde bu yordama ait birleşme noktası da önceki birleşim nokta kümesine dahil olacaktır. Bu ww

w.ja

vadi

li.co

m

Page 27: Ilgiye Yonelik Program Lama ASPECTJ HDUZGUN

27

durumda programcı yazdığı her birleşim nokta kümesi üzerinde mutlak bir hakimiyete sahip olmalıdır. Bu da büyük programlar için oldukça zordur.

KAYNAKÇA

• http://aosd.net/conference• http://aosd.net/wiki• http://eclipse.org/aspectj/• http://www.aspectbench.org/• http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html• http://www.codefez.com/Home/tabid/36/articleType/ArticleView/articleId/98/Asp

ectOrientedProgrammingwithTacobymarchoffman.aspx• http://www.cis.uab.edu/gray/Research/C-SAW/

www.

java

dili.

com