Yazılımda bilginin yarı ömrü ne yazık ki altı ayın altına düşmüş durumda. Yazılımcılar eskiye nazaran daha çok bilgi edinmek zorundalar. Bunda yazılımda soyutlamanın hızlanmasının büyük bir rolü mevcut. Soyutlama ve geldiğimiz noktayı bu yazımda kaleme almaya çalışmıştım.
Soyutlama işlemi bilginin evrimi için gerekli bir süreç. Evrimin olmadığı yerde gelişme olmaz. Evrim süreci bilginin geçerliliğini ispat etmekle mükellefken, soyutlama süreci de bilginin kullanıldığı anlamına gelmekte. İnsanlık var olduğu sürece, bu ilişki bilginin bir balon gibi şişip, sonsuzluğa doğru büyüyeceği anlamına geliyor, çünkü insanoğlu doğası gereği soyutlamadan yapamaz. Bu yüzden soyutlama işlemini bilgisel evrimin akaryakıtı olarak görebiliriz.
Akaryakıt demişken; Gaza basıldığında aracın hızlanması gibi, soyutlama yapıldıkça bilgi çoğalır. Bilgi çoğaldıkta soyutlama kolaylaşır. Soyutlama hızlandıkça daha çok bilgi oluşur ve bu soyutlamayı daha da kolaylaştırır ve hızlandırır. Kısaca soyutlama hızlandıkça kendisi için gerekli ortamı daha kolay oluşturur ve daha da hızlı hareket etmeye başlar. Yani soyutlama belli bir seviyeden sonra kendi kendinin gazına basarak, kendi işleme sürecini hızlandırır. Bunun önüne geçmek mümkün değil. Nitekim yazılım camiasında yirmi sene öncesini ve günümüzü kıyasladığımızda, soyutlama işlemin hangi hıza ulaştığını apaçık görebilimekteyiz.
Bu ilişkiyi anladıktan sonra, yazılım dünyasındaki yeniliklerin gökten zembille inmediği ve doğal bir bilgisel evrim sonucu oluştukları görülmektedir. Şimdi isterseniz güncel birkaç konuya ve nasıl evrildilerine göz atalım.
Mikroservis Mimarisi
Oluşma Nedeni
Monolitik uygulamaların bakım, gelişim ve kullanım süreçlerindeki komplikasyonlar.
Temel Prensip
Temelinde SRP – Single Responsibility Principle (link1, link2) (tek sorumluluk prensibi) yatıyor. Uygulama tek bir işten sorumlu küçük modüllere bölündüğü taktirde, bakımı ve geliştirilmesi daha da kolaylaşıyor. Her modülün kendi veri tabanı mevcut ve modüller arası iletişim rest ya da event messaging üzerinden gerçekleşiyor. Mikroservis mimarisini zor kılan veri izolasyonu ve modüller arası iletişim.
Evrilme süreci
- Tek bir veri tabanı olan monolitik uygulamalar.
- Dağıtık sistemlere geçiş (socket, rpc, http, ejb).
- SOA ile webservis mimarileri.
- Enterprise servis bus mimarileri.
- Event driven mimariler.
- Webservis mimarilerinin ve xml bazlı veri alışverişinin kullanınım zorluğu sonucu oluşan rest/json bazlı mikroservis uygulalar.
Bir sonraki evrilme aşaması
Picoservis, lambda ve serverless mimariler
Reaktif Programlama
Oluşma Nedeni
Imperatif programlama paradigmasının veri akışı (stream) ile oluşan durum değişikliklerine (event) cevap verecek yapıda olmaması. Örneğin bir MS Excel uygulamasında bir hücrenin değerinin değişmesi ile bağlantılı hücrelerde gerekli değişiklikler otomatik yapılır. Imperatif kodlanmış bir uygulamada değer ataması yapıldıktan sonra, yapılan değişiklikler değişkenin kullanıldığı diğer işlemlere yansımaz.
Temel Prensip
Temelinde iteratör ve observer tasarım şablonu yatıyor. Uygulama parçaları doğrudan (senkron) kullanıcı isteklerini cevaplamak yerine kendilerine gelen (abone oldukları veri akışlarından (stream)) durum değişikliklerine (event) reaksyon gösteriyorlar. Bu onların asenkron çalışarak, daha az sistem kaynağı ile daha çok iş yapmalarını mümkün kılmakta. Böyle bir mimari de kodun bakımı ve geliştirilmesi daha da zor. Veri akıcı nitelikte (stream) ve asenkron işlem görüyor.
Evrilme süreci
- Her kullanıcı isteğinin bir işletim sistemi süreci (process) tarafından cevaplanması (örneğin apache preforking modeli).
- Her kullanıcı isteğinin bir thread tarafından cevaplanması (örneğin tomcat uygulama sunucusunun çalışma modeli).
- Çok çekirdekli donanım mimarilerin gelişmesi.
- Fonksiyonel programlamanın veri akışı üzerinde yan etkisiz transformasyon işlemlerini kolaylaştırması.
- Bloke olmayan işlemler (örneğin Java NIO API, Java Streaming API, CompletableFuture).
- Event looping mekanizması ile kullanıcı isteği ile threadler arasındaki birebir bağın kaldırılması ve çok az sayıda thread ile aynı sayıda kullanıcı isteklerinin işlenmesi (örneğin Eclipse Vert.x çatısı).
- RxJava gibi çatıların fonksiyonel programlama tarzı ile reaktif programlamayı mümkün kılmaları.
Bir sonraki evrilme aşaması
Mikroservis ve reaktif mimariler.
Reaktif Mimari
Oluşma Nedeni
Gerçek zamanlı bilgi işlem gereksinimi.
Temel Prensip
Temelinde Loose Coupling (link1, link2) (esnek bağ prensibi) yatıyor. Nihai amaç veri akışı (stream) üzerinde geniş hacimli ve gerçek zamanlı asenkron işlem yapabilmek.
Evrilme süreci
- Event bus mimarilerinde mesaj dağıtımı aracılığı ile mevcut servislerin işlem yapmalarının sağlanmaları.
- Hadoop ve MapReduce ile batch güdümlü büyük veri (big data) işleme kolaylığı.
- Kafka gibi yüksek ölçeklenebilir messaging sistemlerinin oluşturulması.
Bir sonraki evrilme aşaması
Event güdümlü streaming mimarileri (event driven streaming architectüre)
Angular
Oluşma Nedeni
Javascript bazlı uygulamaların bakım ve geliştirilmesinin zorluğu. Buna paralel frontend uygulamalarında backend uygulama geliştirme tekniklerinin eksikliğinin hissedilmesi (katmanlı mimarı, test güdümlü yazılım vs).
Temel Prensip
Üç katmanlı mimarilerde kullanılan servis katmanı, veri katmanı, dependency injection, test güdümlü yazılım ve modüler yapılar Angular ile gösterim katmanına taşınmış oldu. Nihai amaç bu yeni tekniklerle bakımı ve geliştirilmesi daha kolay gösterim katmanları (frontend – presentatıon layer) oluşturmak.
Evrilme süreci
- Web tarayıcılarının Javascript desteği ile web uygulamalarında interaksiyonun artması.
- Interaktif uygulamaların Java appletler ile web tarayıcısına taşınması.
- Perl ve benzeri diller ile CGI (Common Gateway İnterface) bazlı uygulama geliştirme.
- Java JSP ve Servlet teknolojileri ile uygulama mantığının backend güdümlü yapılması.
- Java Server Faces (JSF) ve Struts gibi MVC (Model-View-Controller) bazlı çatıların kullanımı.
- Jquery ve Ajax ile interaktif arayüzlerin oluşturulması.
Bir sonraki evrilme aşaması
Elektriklerin kesilmesi ile tüm teknolojinin son bulması :)
Bugün üniversite mezunu bir yazılım mühendisinin çalışma hayatına adım attığını düşünelim. Bu şahıs bilginin evriminden doğan en son durum ile muhattap olmak zorunda, yani bir frontend yazılımcısı olmak için angular, typescript, javascript, react ve benzeri dil ve teknolojilere, bir backend yazılımcısı olmak istiyorsa fonksiyonel, imperatif, nesneye yönelik programlama paradigmaları yani sıra reaktif programlama, reaktif mimariler, katmanlı mimariler
gibi konulara da hakim olmak zorunda. Bu şahsın “işin temellerinden başlamam gerekiyor, assembly öğreneyim” deme lüksü yok. O, şimdi gelinen soyutluk seviyesinin en üzerinde oturuyor ve bu noktadaki araç, gereç, teknik ve metotları kullanmak zorunda! Geldiğimiz soyutluk seviyesinde hem bilginin genişliği hem de derinliği artmış durumda. Sizce bu şahıs yapacağı işte ne kadar başarılı olabilir? Siz de onun içinde bulunduğu durumun pek parlak olmadığını düşünüyorsunuz ve onun için üzülüyorsunuz değil mi? Ama merak etmeyin, bahsettiğimiz bu şahıs 10 sene sonra gerekli tüm bilgi ve tecrübeyi edinmiş olacak ve işini hakkını vererek yapacak, öyle değil mi? Bu sadece soyutlama işlemi tamamen durduğu zaman olabilir. Ama soyutlama işlemi devam edeceği için 10 sene sonra bu şahıs daha büyük bir soyutlanmış bilgi dağının eteğinde bulacak kendisini. Bu sorunu çözmenin tek bir yolu var: “soyutlanmış bilginin tepesine çıkmak yerine, temeline doğru derin dalış yapmak yani işi temel prensiplerinden ve yapılarından yola çıkarak, anlamak, öğrenmek ve uygulamak.
OSI referans modelini bilir misiniz? OSI bilgisayar ağlarında katmanları ve aralarındaki ilişkileri ve protokolleri tanımlayan bir modeldir. Ağ üzerinden iletişim içinde olan iki bilgisayar sistemi OSI modelinin en üstünde olan uygulama katmanından aşağıya doğru inerek veri alışverişi yaparlar. OSI modelinde soyut olan en üst katmandan yavaş yavaş somutlaşmaya başlayan alt katmanlar doğru inilir ki soyut bir yapı olan uygulama katmanı işi somut ve elle tutulabilir olan ağ kablosu ve oradan da telefon kablolarına delege eder.
Aşağıda yer alan tweet ile OSI modeli ve yazılımcının problem çözme yetisi arasındaki bağı kurmaya çalışmıştım.
Yazılım sistemlerindeki sorunlar OSI katmanları aşağı doğru inilerek çözülür.Yazılımcı bu katmanları tırmanarak,uygulama katmanına yerleşmediyse,sorun çözme kabiliyeti sadece algorıtma ve veri yapıları analizi ile sınırlı kalacaktır ki onların da çoğu OSI katman. inmek içindir.
— Özcan Acar (@öezcanacar) October 22, 2019
Günümüzde kurumsal alanda kullanılan uygulamaların hepsi OSI tabanlı, çünkü sadece verileri bir veri tabanında tutmak için bile ağın kullanılması gerekiyor. Yazılımcının bir uygulama bünyesinde oluşan hataları anlayabilmesi ve giderebilmesi için OSI katmanlarını aşağıya doğru inmesi gerekebilmektedir. OSI modelinde katmanlar arası gidip, gelebilen bir yazılımcı gerçek anlamda problem çözme yetişine sahiptir. Yazılımcı sadece uygulama katmanında yani en üst katmanda kaldığı ve diğer katmanları göz ardı ettiği taktirde, alt katmanlarda ne olup, bittiğinden bihaber kod yazarı olmaktan ileri gidemez.
Ben OSI modelinin bilginin evrimi ve soyutlamanın getirdiği problemlerle baş etmek için de kullanılabilecek bir referans modeli olduğunu düşünüyorum. Soyutluk ilk etapta işimizi kolaylaştıran bir yapı. Lakin aynı zamanda bizi temel prensiplerden ayıran derin bir kuyu. Soyutluk ile baş edebilmek için o kuyunun dibine inmeyi göze almamız gerekiyor. Örneğin o kuyunun başındayken gördüğümüz mikroservis mimarisi ise, en bidinde tek sorumluluk tasarım prensibi olduğunu öğrenebilmemiz için kuyunun dibine inmemiz gerekli. Eğer mikroservis mimarının temelinde ne olduğunu bilmiyorsak, onu neden kullanmamız gerektiğini de bilmemiz mümkün olamaz. Örneğin bu temel prensibi anlamamış bir yazılımcı mikroservislerin nasıl bir yapıda olmaları gerektiğini bilmediğinden dolayı, zaman içinde birden fazla işten sorumlu küçük monolitik yapıda mikroservisler geliştirecektir. Aynı şekilde temel prensibi anlamış olan bir yazılımcı üzerinde çalıştığı mikroservis birden fazla sorumluluk sahibi olma eğilimi gösterdiğinde, onu parçalarına bölerek, tek bir işten sorumlu mikroservisler oluşturacaktır.
Burada OSI modeli bir ağ refereans modeli olmaktan çıkıyor ve soyutlama işlemindeki bilgi akumülasyonunu katmansal olarak tanımlayan bir model haline geliyor. Her yeni soyutlama işleminde yeni bir katman oluşuyor ve ne yazık ki her yeni katman ile yazılımcı ile bilginin arasına soyutluk girerek, onu temel prensiplerden koparıyor. Bu onun çok kolay bir şekilde nasıl kullanırım soruna cevap vermesini kolaylaştırırken, neden kullanıyorum sorusuna cevap bulmasını güçleştiriyor.
Soyutlama işleminin bedeli ağırdır. Bilginin kullanımını kolaylaştırır lakin bilgiyi perdeleyerek, nereden geldiğini gizler. Programcılıkta esas mesele bu perdeleri aralayabilmektir.
EOF (End Of Fun)
Özcan Acar
Hocam süper bir yazı olmuş ellerinize sağlık. Yeni mezun olmuş ve sektörde ilk ayını yeni tamamlamış biri olarak beni aydınlattınız. Emekleriniz için teşekkürler.