Arda Çetinkaya Yazılım ve arada kendim ile ilgili karaladıklarım…

Hatırlayacak olursanız son bir kaç yazıdır AOP hakkında bir şeyler paylaşıyordum. İlk iki yazı teorik, son yazı ise biraz daha uygulamaya yönelik olmuştu. Bu yazıda ise, bir önceki yazıda başlamış olduğum örneği biraz daha geliştirip, AOP’ı daha iyi anlamaya çalışacağız. Ama isterseniz önceki yazıları bir hatırlayalım…

  1. ‘Aspect Oriented’ programlama mı…Nedir ki?
  2. Peki ama neden ‘Aspect Oriented’ programlama…
  3. ‘Aspect Oriented’ programlamaya başlıyoruz…Bölüm I

Bu yazıda bir önceki kod alt yapısını üzerinden giderek, AOP kavramında ki Aspect’leri yaratıyor olacağız. Özellikle “Aspect” şeklinde belirtmek istiyorum ki, yarattığımız bazı örnek sınıfları bu şekilde düşünmeye çalışmak, konunun bütününü anlamak adına yardımcı olacaktır. Hatırlarsanız bir önceki yazıda Person diye bir sınıf oluşturmuştuk örnek olarak ve bu sınıfı bir tane konsol uygulamasında kullanarak methodlarını çağırmadan önce nasıl araya girebileceğimize değinmiştim. Yine aynı sınıf üzerinden, onu biraz daha geliştirerek gidiyor olacağız. Bunun için sınıfımızı aşağıdaki gibi yenilememiz yeterli olacaktır şimdilik. Yeni bir özellik ve metod dışında aslında fazla bir şey de yok.

    [Controller]
    public class Person : ContextBoundObject
    {
        private int _age = 0;
        private string _name = "";

        public string Name { get { return _name; } }

        public Person(string name) : base() { _name = name; }

        public int Age
        {

            get
            {
                return _age;
            }
            set
            {
                _age = value;
            }
        }

        public string DoSomething()
        {

            string logMessage = "Person sınıfının DoSomething() methodu çalıştı";
            Console.WriteLine(logMessage);

            return "";
        }
        public void DoAnotherThing(int parameter1, string parameter2)
        {
            Console.WriteLine("Person sınıfının DoAnotherThing() methodu çalıştı");
        }

    }

AOP, yazılımda ki kesişen ilgileri ayırmak için kullanabileceğimiz bir yöntemdi demiştik. Bu ilgiler her yazılım ürününde bir şekilde olan Logging,Exception Handling gibi kavramlar olabileceği gibi, iş kuralları ve bu kuralların işletildiği methodlar da olabilir. Ama genellikle bir biri ile çakışan ilgiler Logging,Exception Handling, Security gibi kavramlar için daha karmaşık olur. Oluşan Exception için uygun kaydı tutmak, ya da bir metod çalıştığında bu metodun çalışmasına dair bazı bilgileri kayıt altına alabilmek bir çok kavramın iç içe girmesine sebep olur. Bu yazıda bu ilgilere biraz daha yer vererek, bu ilgileri AOP yaklaşımı ile nasıl ayırabileceğimizi anlamaya çalışacağız. Örnek olabilecek bir kaç ilgiyi oluşturup, bunu Person sınıfımızda kullanacağız. Bu ilgileri .NET Framework’ünde bulunan Attribute‘lar ile yaratıp, nesnelerimize,metodlarımıza ve nesnelerin özelliklerine bağlayacağız. Aşağıdaki gibi bir kaç nesne, örnek olması adına yeterli olacaktır diye düşünüyorum.

Devam…

 

 

Bir önceki yazılarda hatırlarsanız, AOP’in ne olduğunu, neden gerekli olabileceğini anlatmaya çalışmıştım. Şimdi de biraz kod üzerinden giderek AOP kavramlarını anlatmaya çalışacağım. AOP için birbiri ile kesişen ilgileri ayırmak için kullanabileceğimiz bir yaklaşım demiştik hatırlarsanız. Kod üzerinden giderek bu ilgileri nasıl ayırabileceğimizi 2 kısım şeklinde olacak bir yazı dizisi ile anlatmaya çalışacağım. Bu ilk kısımda birbiri ile kesişen ilgileri ayırmak için bir alt yapı oluşturacağız. Daha sonra ki yazımda ise yarattığımız nesnelere yeni ilgiler vererek bu alt yapı sayesinde ilgilerin aslında hiç kesişmeden basit bir biçimde uygulandığını göreceğiz. O zaman başlayalım…

Bu yazı için .NET Framework içerisinde bulunan ContextBoundObject sınıfından faydalanacağız. Bu noktada .NET Framework’de direk olarak bir AOP desteği olmadığı hatırlatmak isterim. Sadece .NET Framework’ün bize sunduğu sınıf ve metodlar ile bu yaklaşımı biraz olsun oluşturmaya ve daha iyi anlamaya çalışıyor olacağız.

Öncelikle ContextBoundObject sınıfının ne olduğu kısaca anlatmaya çalışacağım. Biraz sonra aşağıda vereceğim örneğin daha anlaşılır olması adına gerekli olacağına inanıyorum.

Bir içeriğe(context) ve bu içeriğin kurallarına bağlı olan nesnelere, içeriğe bağlı nesneler deniyor, yani context-bound objects. Peki içerik ne? Belli özelliklerin ve kullanım kurallarının kullanıldığı, nesnelerin bir araya geldiği oluşumlar diyebiliriz. Yani bir nesne bir içeriğe dahil olduğu ya da bağlandığı zaman o içeriğin özelliklerini ve kurallarını uygulamak durumunda oluyor. Bir nesne yaratılırken var olan bir içeriğe ya da meta-data’sında bulunan Attribute’lara(özelliklere) göre yaratılacak yeni bir içeriğe bağlanabilir. Burada ki özellik kavramı da ContextAttribute sınıfı ile .NET Framework içerisinde tanımlanmakta. Biraz daha geniş ve ayrıntılı bilgiyi buradaki MSDN içeriğinden öğrenebilirsiniz. Ama bizim için şimdilik bu kadarı yeterli olacak.

Yukarıda özetlemeye çalıştığım ContextBoundObject sınıfı ile oluşturacağımız nesnelerin bir içerik dahilinde oluşmasını sağlayacağız. Daha sonra bu içerik içerisinde ki kurallara göre kesişen ilgileri kontrollü bir şekilde yönetebileceğiz. Bunu nesneleri yaratırken, tam yaratmadan önce bazı kontrolleri yaparak, nesnenin bir metodunu çağırırken, tam çağırmadan önce bazı kontrolleri yaparak ya da nesnenin özelliklerini değiştirirken, tam değiştirme aşamasından önce yine bazı kontroller yaparak yapacağız. Burada ki kontroller de aslında birbiri ile kesişen ilgiler olacak. Biraz karışık oldu sanırım ama kod örnekleri ile daha net anlaşılacağına inanıyorum.

Öncelikle ContextBoundObject sınıfından türeyen bir Person sınıfı yaratalım…

 public class Person : ContextBoundObject
 {
        private int _age = 0;
        public Person():base()
        {

        }
        public int Age
        {
            get
            {
                return _age;
            }

            set
            {
                _age = value;
            }
        }

        public string DoSomething()
        {
            return String.Format("Person sınıfının DoSomething methodu çalıştı");
        }
 }

Fark etmiş olduğunuz gibi ContextBoundObject’ten türemesine rağmen pek bir farklılığı yok. Bu nesnenin yaratıldığı içeriğin özelliklerini(Attribute) belirlememiz lazım ki, yaratıldığı zaman o özelliğin sağlayabileceği yöntemler ve özellikler ile nesnenin üzerinde kontroller yapabilelim. Bunun için aşağıdaki gibi bir kod bloğu ile ContextAttribute’dan türeyen bir Attribute yaratmamız lazım.

Devam…

Bir önceki yazımda, AOP’in birbiri ile kesişen ilgileri ayırmak ve basitleştirmek için kullanabileceğimiz bir yaklaşım olduğunu söylemiştim hatırlarsanız. Ve hatırlarsanız bir tane de pseudo kodu ile bir insanın yaşam sürecini örneklendirmeye çalışmıştım. Yaşam döngüsünde birbiri ile kesişen iglileri görmüştük. Biraz daha anlaşılır olması adına daha sık karşımıza çıkan problemleri bu yazıda ele almaya çalışacağım.Bu sayede AOP’ı ve hangi sorunlara çözüm sunduğunu anlamak daha kolay olacaktır. İlk olarak aşağıdaki metod ile başlayalım.

public ResultSet SearchCustomer(string username, string customerName,string customerSurname)
 {
              try
            {
                if (!IsExists(username))
                    throw new DoesNotExistsException();

                if (!HasAccess(username))
                    throw new AccessDeniedException();

                Logger.Write("Search will be done with CustomerName:{0} CustomerSurname:{1}",customerName,customerSurname);

                ResultSet results = Database.Search(customerName, customerSurname);

                Logger.Write("Search is successfully done");

                return results;
            }
            catch (Exception ex)
            {

                Logger.Write(ex.Message, "ERROR");
            }

            return null;
 }

Müşteri adı ve soyadına göre arama yapan, arama yaparken bazı kontrolleri gerçekleştiren bir metod var yukarıda. Arama yapan kullanıcıyı kontrol eden,daha sonra bu kullanıcının durumuna göre başka bir kontrol yapan, kayıt eden ve sonra arama operasyonunu gerçekleştiren ve bir hata olursa yine bunu kayıt altına alan bir metod dikkat ederseniz. Bir çok farklı ilgi aslında iç içe…Daha doğrusu kesişiyor. Bu tarz ilgiler aslında bir çok yazılım projesinde önemli yer kaplıyor. Bu tarz ilgilerin birden fazla metod içerisinde kullanıldığını düşünün…Search() metodunun içerisinde yapılan kontrollerin, aynı gereksinimlerden dolayı SaveCustomer() metodunda da yapılması gerektiğinde birbirini tekrarlayan, bir değişiklikte bir çok yeri etkileyen kod parçaları ortaya çıkacaktır. Bunlar zaman zaman soruna, zaman zaman da karmaşıklığa yol açar bildiğiniz üzere…Ve bu şekilde iç içe girmiş karmaşıklıkları yönetmek oldukça zor olacaktır.

Devam…