Bu yazıda, Reaktif Programlamanın temel kavramlarını göstereceğim. Gerçek bir programlama deneyimine kendinizi hazırlayın. Örnekleri oluştururken RxPython kütüphanesinden faydalanacağım.
Günümüzde herkes (Türkiye’de pek değil) Reaktif programlamadan bahsediyor ve Reaktif programlama adlı bu yeni şeyi birazcık öğrenmeye meraklıysanız tamda yerine geldiniz. Belki de birkaç yerde kullanıldığını gördünüz ama yine de biraz kafanız karışık ve açıklamalar istiyor olabilirsiniz. (Herkes gibi)
İlk önce karşı karşıya olduğumuz problemin ne olduğunu kendi kafanızda sorgulamalısınız. Neden ihtiyacınız var? Ne gibi bir sorununuza çözüm arıyorsunuz?
Asenkron çalışma yapısına neden ihtiyacımız var?
Cevap biraz basit olacak, sadece kullanıcı deneyimini geliştirmek istiyoruz. Uygulamamızı daha duyarlı hale getirmek istiyoruz. Kullanıcılarımıza ana iş parçacıklarında sorunlar oluşturmadan süper bir kullanıcı deneyimi sunmak istiyoruz, yavaşlatarak kullanıcılarımızı sıkmak istemiyoruz. Böylelikle daha iyi hizmet sunmuş olacağız.
Arka planda yapmak isteyeceklerimiz bizim işlerimizi uzatacağı da bir gerçek, Ayrıca mobil cihazlar ağır işleri yapmak için çok güçlü olmadığından, sunucularımızda ağır işleri ve karmaşık hesaplamaları yapıyoruz. Bu nedenle, ağ aksiyonlarının asenkron çalışmaya ihtiyacımız var.
Reaktif Programlama Nedir?
Reaktif programlama, yan etkileri de işleyebilen bir programlama paradigmasıdır.
Bir örnek vermem gerekirse; 60 gramlık bir kahveyi 3’e bölerek 5’er dakika öğütüyorsunuz. Ama bunun yanında yapmanız gereken başka işler de bulunuyor. İşte bu işleri de yaptığınızda bu durumu etkileyen yan etkileri de işleme almış olacaksınız.
Reaktif Programlar kod akışını takip etmek yerine olayları(events) takip ederler. Akış devam ederken olayları takip etmek oldukça mantıklı bir durumdur. Akış sırasında pek tabi birçok işlemde yapılabilir. Olayı daha iyi anlayabilmeniz için aşağıdaki görsele dikkatlice bakmanızı öneririm.
Buradan anlayacağınız olay ise reaktif uygulamalar aynı anda birden çok olayı takip ederek aksiyona girebilen uygulamalar olduğudur.
Yani gerçek hayat da ki gibi anlık oluşan durumlara göre tepki verilir. Gündelik yaşantınızda anlık gelişen durumlar gibi, reaktif programlamada işte bu noktada canlı bir organizma gibidir.
Oluşan bir olay var ise bu oluşan olaya verilecek bir tepki olmak zorundadır.
Başka bir deyişle, Rx programlamasında bir bileşen tarafından yayılan veri akışları ve Rx kitaplıkları tarafından sağlanan alttaki yapı, bu değişiklikleri, bu veri değişikliklerini almak üzere kaydedilen başka bir bileşene yayacaktır. Bu kısım işin hikâye kısmı ancak kısaca şu 3 parçaya bölerek güzel bir şekilde açıklayabiliriz.
- Gözlemci: Veri akışının gözlemlenmesinden başka bir şey değildir. Bir iş parçacığından diğerine ve farklı iş parçacığına çevrilebilecek verileri düzenler. Temelde, verileri periyodik olarak ya da yapılandırmalarına göre yaşam döngüsünde yalnızca bir kez işleme alır. Gözlemciye olaylara dayalı bazı belirli verileri işleyebilecek ve yardımcı olmasına imkân sağlayacak çeşitli operatörleri vardır. Bir katman olarak düşünürsek verileri işler ve diğer bileşenlere gönderirler. Şimdilik, bunu tedarikçiler olarak düşünebilirsiniz.
- Gözlemciler: Gözlemciler ilk baştaki gözlemcinin gönderdiği veri akışı ile ilgilenirler. Gözlemciler, gözlemci tarafından gönderilen verileri almak için gözlemciler yapıları sayesinde ilgilenmeye başlarlar. Gözlemlenebilir veriler elde edildiğinde, gözlemci, verileri teslim alır. Burada, JSON yanıtını ayrıştırma veya kullanıcı ara yüzünü güncelleme gibi çeşitli işlemleri gerçekleştirebilirler. Gözlemcilerden atılan bir hata varsa, gözlemci bunu daha sonra kendi içinde değerlendirecektir.
- Zamanlayıcılar: Rx’in asenkron programlama için olduğunu ve bir iş parçacığı yönetimine ihtiyacımız olduğunu unutmamamız gerekiyor. Zamanlayıcılar, gözlemci ve gözlemcilere hangi dizinde çalışacaklarını söylerler. Gözlemcilere hangi dizinde gözlem yapmaları gerektiğini söyleyebilirsiniz. Ayrıca, gözlemlenebilir nesneye, hangi iş parçacığında çalışması gerektiğini bildirebilirsiniz.
Durumu bir örnek ile açıklamamız gerekirse;
from rx import Observable, Observer
def push_five_strings(observer):
observer.on_next("Alpha")
observer.on_next("Beta")
observer.on_next("Gamma")
observer.on_next("Delta")
observer.on_next("Epsilon")
observer.on_completed()
class PrintObserver(Observer):
def on_next(self, value):
print("Received {0}".format(value))
def on_completed(self):
print("Done!")
def on_error(self, error):
print("Error Occurred: {0}".format(error))
source = Observable.create(push_five_strings)
source.subscribe(PrintObserver())
Yukarıdaki örnekte Bir Observable.create ()
metodu kullanılarak öğeleri gözlemciye ileten bir işleve gönderilir. Observer, on_next ()
, on_completed()
ve on_error ()
işlevlerini uygular.
on_next ()
öğeleri iletmek için kullanılır.on_completed()
daha fazla öğe gelmeyeceğini işaret edeceğinde tetiklenir.on_error()
bir hata sinyali aldığında tetiklenir.
Çıktı ise aşağıdaki gibi olacaktır.
Received Alpha
Received Beta
Received Gamma
Received Delta
Received Epsilon
Done!
Bu konuda özellikle son dönemlerde geliştirilen pek çok proje görebilmek mümkün.
Örneğin: google’nin geliştirmekte olduğu android projesi Agera
Ayrıca konu hakkında daha detaylı bilgilere ulaşmak isterseniz. Resmi dokümanları kontrol edebilirsiniz.