Çok uzun bir ara vermiştim fark etmiş olduğunuz üzere…Ama şimdi kaldığım yerden devam ediyor ve fazla uzatmadan hemen bu yazının konusuna geliyorum… .NET Framework 4.0 ile gelen iki yeni arayüzü kısaca anlatmaya çalışacağım.

IObservable<T> ve IObserver<T> yeni gelen arayüzlerimizden…Bu arayüzler “push-based notifications” diye literatürde yer alan sistemler oluşturmamız için faydalanabileceğimiz arayüzler. “push-based notifications” nedir ile başlasak sanırım daha kolay olacak bazı şeyler. Artık bir çok kişinin kullandığı sosyal paylaşım sitelerinden örnekler verebiliriz daha iyi anlamak için. Facebook’da örneğin, sayfa ile her hangi bir etkileşim olmadan zaman zaman sağdan soldan “1 tane mesajınız var”, “X kişisi Y’nin fotoğrafını beğendi” gibi bildirimler alıyoruz. Bu tarz bildirimlere “push-based notifications” diyoruz. Türkçeleştirmek için kasamadım açıkcası ama basitçe bir nesnenin, kendisine bağlanan ya da üye olan parçalara bildirimler göndererek, kendinde olan değişimleri bildirmesi olarak açıklayabiliriz. Gözlemci ve gözlenen olarak düşünürsek biraz daha netleşebilir sanırım. Bütün bu kavramlar aslında mevcut event yaklaşımı ile üstü kapalı olarak bize sunulmakta tüm yazılım geliştirme dillerinde. Ayrıca “Observer” tasarım kalıbı şeklinde de literatürde yerini uzun süredir korumakta.

IObservable ve IObserver arayüzleri de bu tasarım kalıbının .NET Framework’de ki yansıması. Peki neden yeni olarak .NET Framework 4.0 ile geldi ya da mevcut event yapısı zaten bu kavramları karşılamıyor mu sorularını sorabilirsiniz…Gelişen ihtiyaçlar ve kullanıcı eğilimlerinden dolayı asenkron çağrılar ve dağınık olay bazlı(distrubted events) yaklaşımları kendi sistemlerimizde, kendimize özgün yöntemler ile kullanmamız gerekebiliyor. Bundan dolayı bu iki arayüz ile daha kontrollü bir şekilde kendi “push-based notification” tarzı uygulamalarımızı .NET Framework ile daha kolay geliştirebiliyoruz. Bir örnek ile devam edip biraz daha netleştirelim.Yabacağımız örnek basit bir konsol uygulaması olup, doların yükselişini simule eden ve bu yükselişi takip eden bir uygulama olacak. Oldukça basit…Yine standart olarak kod üzerinden açıklamalar ile anlatmaya çalışacağım. O zaman başlıyoruz…

    //IObservable arayüzünden gözlemnecek nesnemizin sınıfı yaratıyoruz.
    //T tipindeki nesne yarattığımız nesne ya da daha temel bir nesne olabilir.
    //IObservable arayüzünden türüyen sınıf, arayüzden gelen Subscribe()
    //metodunu tanımlamak durumda. Bu metod ile bu nesnemizi gözleyecek
    //nesneleri tanımlıyoruz.
    public class Dolar : IObservable
    {
        //Nesnemizi birden fazla gözlemci gözleyebileceği için
        //List tipinde bir nesne ile gözlemcileri saklayabileceğimiz
        //bir koleksiyon tanımlıyoruz.
        private List> _subscribers;
        private int _amount;

        public Dolar()
        {
            _subscribers = new List>();
        }

        public int Amount
        {
            get
            {
                return _amount;
            }
            set
            {
                _amount = value;
                //Nesnemizde oluşacak değişiklikleri gözlemcilere,
                //gözlemcilerin(-ki bunlar IObserver arayüzünden
                //yaratılan sınıflar) OnNext() metodu ile bildiriyoruz.
                foreach (var item in _subscribers)
                {
                    item.OnNext(this);
                }
            }
        }

        //Subscribe metodu IObservable arayüzünden gelen bir metod.
        //Bu metod ile nesnemizi gözlemleyecek diğer nesneleri belirtebiliyoruz.
        //Bir başka deyişle nesnemize abone olacak ve onun değişikliklerinden
        //etkilenecek olan nesneleri alıyoruz.
        //IDisposable tipinde bir dönüş değeri olmasının sebebi, gözlemcilerin
        //gerektiği zaman aboneliklerini iptal ettirebilmelerini sağlıyor.
        //Bu örnekte bu konuya değinmedim.Belki ileride
        public IDisposable Subscribe(IObserver observer)
        {
            if (!_subscribers.Contains(observer))
                _subscribers.Add(observer);

            return null;
        }
    }

Gözlenecek nesnemizin sınıfı oluşturduktan sonra, bu nesne üzerindeki değişiklikleri takip ve kontrol edeceğimiz, gözlemci nesnelerimizin sınıflarını aşağıdaki gibi yazabiliriz.

    //Aşağıdaki örnek sınıfta, IObserver arayüzünden yarattığımız nesne
    //CurrencyTracker nesnesi, Dolar tipinde ki nesneleri gözlemleyecek.
    //IObserver arayüzünden gelen 3 tane zorunlu metod var.
    //OnNext() metodu ile değişen datayı gözlemciye bildiriyoruz,
    //OnError() metodu ile hata oluştuğu durumları gözlemciye bildirebiliyoruz,
    //OnCompleted() metodu ile de bildirimlerin tamamlandığı bilgisini verebiliyoruz.
    public class CurrencyTracker : IObserver
    {
        public CurrencyTracker()
        {

        }

        public void OnCompleted()
        {
            Console.WriteLine("İşlem Tamamlandı");
        }

        public void OnError(Exception error)
        {
            Console.WriteLine("Hata oluştu");
        }

        public void OnNext(Dolar value)
        {
            Console.WriteLine("Dolar'ın değeri:{0} ",value.Amount);
        }
    }

    //Bu örnek için, yukardaki diğer gözlemciye benzeyen başka bir
    //gözlemci, aynı mantıkla çalışmakta.Ek olarak OnNext() metodunda
    //gelen veri değerini kontrol ediyor.
    public class LimitTracker : IObserver
    {

        public LimitTracker()
        {

        }

        public void OnCompleted()
        {
            Console.WriteLine("İşlem Tamamlandı");

        }

        public void OnError(Exception error)
        {
            Console.WriteLine("Hata oluştu");
        }

        public void OnNext(Dolar value)
        {
            if(value.Amount>70)
                Console.WriteLine("Dolar'ın değeri çok yüksek: {0} .Kriz olabilir.", value.Amount);
        }
    }

Son olarak ise yazdığımız kodların nasıl çalıştığını görmek adına aşağıdaki gibi basit bir konsol uygulaması yazıyoruz.

    class Program
    {
        static void Main(string[] args)
        {

            Dolar d = new Dolar();
            CurrencyTracker ct = new CurrencyTracker();
            LimitTracker lt = new LimitTracker();

            //Dolar nesnemize abone oluyoruz ve gözlemlemeye başlıyoruz
            d.Subscribe(lt);
            d.Subscribe(ct);

            //1000 milisaniye de bir Dolar tipindeki nesnemizin Amount değerini
            //değiştiriyoruz.
            Timer t = new Timer((s) =>
            {
                d.Amount = new Random().Next(100);
            }, null, TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1000));

            Console.ReadLine();
        }
    }

Örnek uygulamamızın çıktısı da aşağıdaki gibi olacaktır…

Şimdilik bu kadar…Oldukça basit bir örnekle .NET 4.0 ile gelen IObserverve IObservableaçıklamaya çalıştım, umarım biraz olsun faydası olur.

Örnek projeyi buradan indirebilirsiniz…