İyi kavramının 'maalesef' herkese göre değişiklik gösterebildiği aşikar ve bence ana çıkış noktası beklentiler olup yazılım ekosistemi bunun en somut örneklerindendir. Geliştirici ile paydaşlar veya müşterinin 'iyi' beklentileri tamamen farklı olabilir. Bir kullanıcının müthiş gördüğü bir proje aslında çok kötü ya da tam tersi olabilir. Bu yüzden öncelikle bu yazı ile ilgili bir konuya direk açıklık getirmek istiyorum.🙋‍♂️Eğer halihazırda bir yazılım uzmanıysanız ve ömrünüz boyunca sadece tek başınıza kod yazacaksanız ki bu neredeyse imkansıza yakındır; bu yazı size hitap etmemektedir. Yok yazılımcı değil, olmak isteyen biriyseniz ve 'Nasıl Yazılımcı olunur' sorusunu soruyorsanız, yazılımda bir isteği karşılamanın onlarca değişik yolu vardır. Bu yollardan en doğru olanını seçmek, belli bir bilgi ve birikim sonucu oluşan karmaşık bir mekanizmadır. Aslında ne demek istiyorum? 'Ölümüne kod yazarak' yazılımcı olunmaz! Yazılımın aslında gerçek hayattan farklı olmadığını yansıtan bir düşünce tarzı vardır ve bunu kavrayabilmek kod yazmaktan çok daha önemlidir.

Bilgisayar denen aletin ilk yıllarına şöyle bir dönüp öncesinde fark makinesi, hesap makinesi, Turing Makinesi gibi örneklerini düşünelim... Bizim şu an klavye ve monitörle bir satırda yaptığımızı sandığımız işin gerçeğini yapan makineler. Toplama çıkarma bir yana çarpma ve bölme yapabilme becerileri! Aslında hepsi birer 'soft-ware' olsa da o zamanlar böyle süslü bir isim sadece kumaşların yumuşak kısımları için kullanılırmış. Bu kelimenin etimolojik tarihinde bilgisayar için kullanılmaya başlanması 1960'lar civarına denk gelir. Çünkü ilk yıllarında bilgisayarı yapan ve onu programlayan zaten aynı kişi olduğu için işletim sistemi gibi bir ihtiyaç da yok. Hal böyle olunca başlarda yazılım benzeri genel bir tabire de ihtiyaç yokmuş.

Biraz daha yakın geçmişe bakarsak; örneğin uzun yıllar denenip sınanan network topolojilerini düşünün. Bunlar ilk denendiğinde, bilgisayarlar sınırlı sayıda ve sadece ofislerde kullanılan makinelerdi. Daha sonra bir sürü farklı donanım, farklı işletim sistemi... Birbirleriyle bırakın anlaşmayı tanışık bile değillerdi. Zamanla bu tanışıklığı ilerletmek için TCP/IP, FTP, HTTP, NetBEUI gibi protokoller oluşturulmuş ve dünyadaki broadcast geçirmeyen en büyük network olan internette de doğru çalışabilmesi için bu protokollere uyma zorunluluğu getirilmiştir. Yoksa ilk zamanlarında olduğu gibi hiçbir cihaz birbiriyle anlaşamaz bütün yapı arapsaçına dönerdi. Buradan hareketle; şahsen bunun açık kaynak da dahil yazılım dünyasında da böyle olması gerektiğine inanırım. Aslında açık kaynak için keskin kurallar getirmeye çalışmak adına ters gibi gelebilir. Ama inanın açık kaynak projeler, olmayanlara kıyasla çoğundan çok daha gelişmiştir. Çünkü projeye katkı sağlanması isteniyorsa herkesin isteyeceği standardizasyonlar sağlanmalıdır. Yukarıda örneğini verdiğim protokoller gibi yazılımda da böyle standartlar getirilmesi için çeşitli mimariler ve yaklaşımlar ortaya çıkmıştır. Bu yaklaşımlar uzun yıllar sonucu oluşmuştur; çünkü kimse bir başkasının kapısının önüne attığı çöpleri temizlemek istemez! 😒

Ekip Uyumu🎯

merdiven

Yandaki merdiven aslında bahsetmeye çalıştığım senaryonun küçücük bir örneği olabilir. Bu keşmekeşe rağmen, farkında olmadan merdivendeki arkadaşımızın yerinde olmayı isteyen; yani sadece kâr odaklı olmaya zorlanmış, baştan yanlış başlayarak öyle devam etmiş, kısaca katostrofik hale gelmiş projelerde yer almak için sırada bekleyen bir sürü insan doludur. Bu kesimin bir kısmı, bırakın projede sadece çalışmayı, yanlış giden bu yöntemleri öyle içine sindirmiş öyle benimsemiştir ki; bunlar artık onun tek doğrularıdır. Bu yanlışları gündeme getirdiğinizde bunları savunmak için yanıp tutuşurlar.

team jumping

Bir diğer kısmı ise, en azından projedeki yanlışların farkındadır. Bunları kabul eder ve 'bununla yaşamayı öğrenir'🤦‍Şahsen; tamamen profesyonel yaklaşımları uygulayarak büyüdüğünü düşündüğüm bir sürü projede bunu birebir gördüm. Benim de yapmaya çalıştığım zamanlar oldu ama anladım ki ben, bile-isteye kötü kod yazamıyorum; böyle bir "yeteneğim" yok(!) Buna karşın yapmaya çalıştıklarım şahsi meseleler olduğu için değinmeyeceğim. Şurası koca bir gerçek ki; bu anlayışı değiştirmek çok uzun bir yol. Gerçi işin şöyle bir boyutu da var: %100 her şeyin sorunsuz olmasını beklemek zaten fazla ve gereksiz bir iyimserlik, hayalperestlik olur. Yoksa koca google, amazon gibi yazılım devlerinin bile halen neler geliyor başına. Ama çok temel şeylerde yapılacak yanlışlar bir projeyi içinden çıkılmaz hale getirir, benim üzerinde durduğum konu bu. Yani koddaki yan etki kabul edilebilir seviyede olmalıdır. Bağımlılık(en ufak değişkenden, fonksiyondan; sınıfa, pakete kadar...), esneklik, genişletilebilirlik, kararlılık metrikleri, yönetilebilirlik gibi etkenler benim bahsettiklerim... Hatta daha koda geçmeden çıkarılacak analizler, diyagramlar, testler vs. hepsi bir bütündür. Bunları doğru uyguladığınız zaman 'Agile Software Development', 'Extreme Programming', Scrum, Kanban vb. birçok yaklaşım adı havalı geldiği için kullanılan&kullanılmaya zorlanan kavramlar olmaktan çıkıp; işe yarar birer yöntem halini alır. Aslında bu yaklaşımlar 'clean' olan&olmuş&olacak ya da son çare olmasına izin verilecek kod içindir. Eğer kod böyle değilse bunları uygulayamaz, sadece uyguladığınızı sanırsınız; yararından çok zararı dokunur hale gelir. Bu kültürü doğru edinebiliyor olmak yazılım geliştirmekten çok daha önemli bence.

Programlama dili🔮

Bilgisayarı yapan kişi dışında bir kullanan olması ihtiyacı ile doğmuş ve bu yapının üzerine işletim sistemleri inşa edilmiştir. Diğer türlü o kadar karmaşık bir yapıdır ki şu an yazdığımız bir satırlık kodu yazabilmek demek saatleri alacak bir süreçtir. Bu yüzden günümüz modern dillerinden herhangi birisi ile introduction bitip nesne yönelimli programlamaya gelene kadar, öncesindeki diller ile öğreneceğiniz birçok bilgiyi zaten edinirsiniz. Çünkü bu diller de eskiden geçerliliği sayılan birçok dilin kullanışlı özelliklerini bünyesinde barındırdığı ve önceki dillerde bulunmayan esnekliği programcıya sağladığı için bu kadar rağbet görmektedir. Ancak özellikle platforma özel donanım özelliklerinden dolayı halen özellikle tercih edilen diller de vardır.  Donanım olmasa da başka bir açıdan örnek olması için; çoğu bankada yıllar önce COBOL ile yazılmış bazı sistemleri baştan aşağı kayıpsız değiştirmek aşırı maliyetli olduğu için halen bu dil ile yürütülen eskiden yazılmış çok sayıda bankacılık operasyonu bulunur.

Programlama Dilleri Soyağacı - Etkileşim içindeki diller

Eğer gömülü sistemleri bir kenara bırakırsak, öncesindeki birkaç dilde daha yer almasına rağmen asıl C++ ile Bjarne Stroustrup tarafından öne çıkarılan nesne yönelim konseptinin büyüyen projelerden soğumamanız için çığır açtığını düşünürüm. 'Projenin büyümesi' ile kod satırlarının çokluğunu ya da kullanım sayısı gibi şeylerden bahsetmiyorum. Hatta Bill Gates'in bununla ilgili çok güzel bir sözü vardır: "Program ilerleyişini kod satırlarının sayısıyle ölçmek, bir uçak yapımının ilerleyişini uçağın ağırlıyla ölçmek gibidir." Proje büyümesi ile kabaca projenin uygulama tarafına verdiği cevaptan bahsediyorum. Bunu sağlayabilmek için katmanlar arasındaki iletişiminiz ve soyutlamanız çok iyi olmalıdır ki yazdıklarınızı gerçek dünyada olduğu gibi düşeünebilesiniz. İşte bunu kısmen sağlayan nesne yönelim yaklaşımıdır. Nesne yönelimli programlamanın temelleri, bundan 50 sene kadar önce Simula programlama dili ile Ole-Johan Dahl ve Kristen Nygaard tarafından atılmıştır. Hoş, nesne yönelimin de kullanılmaması gerektiğini savunan çok küçük bir kesim var ama ben bunlardan değilim.

Yani çok karmaşık olmayan bir operasyonda yapılacak sınırlı sayıda iş varsa ve bu iş için milisaniyeler seviyesinde hız hayati önemliyse, bunun için ille de nesne yönelim aranmaz. Daha doğrusu 'nesne' diye bir kavram aranmaz. Örneğin bir araba montaj hattındaki robot kolun yaptığı bir işin koordinasyonu için milisaniyeler çok önemlidir, yani erken ya da geç yapacağı iş zincirleme yanlışlıklara yol açacağı için burada önceliğiniz soyutlama değil bu koordinasyonun düzgünlüğü olmalıdır. Yine araçlardan gidersek; ABS, ASR, ESP gibi güvenlik sistemlerini ve bunlardaki zamanlamanın önemini düşünün. Bunların en can alıcı olanı 30 ms gibi bir sürede tamamen şişmesi gereken airbag düşünülebilir. Aracın ivmelenmesini ölçekerek kaza yaptığını anlayan sistemdeki bir gecikme asla kabul edilemez. Bu yüzden üretici cihazı kontrol için bir nevi kendi sade dilini geliştirir. Kısaca nesne yönelim, bu gibi örnekler dışında yazdığımız 'uygulama' sayılabilecek işler seviyesi içindir. İşin aslı nesne yönelim şu an böyle tek bir makalenin bir köşesine sığmayacak kadar geniş bir kavram, kıymeti bilinmesi gereken apayrı bir yaklaşımdır.

Burada teknoloji ile dili ayırmak lazım. Bir balta bile insanoğlunun işini kolaylaştırdığı için sonuçta teknoloji olarak kabul görür. Bir teknoloji olmadan da yapacağınız işi yine yaparsınız yalnız aradaki zaman ve iş gücü kaybı su götürmez bir gerçektir. Ancak bu bazen insanı garip bir ikileme sokuyor. Yazmanız gereken satırlar kalkmış oluyor ama mutlaka yapılan işte araya girme ihtiyacı doğuyor. Bunu sizin yerinize başkaları bir nevi "otomatikleştirdiği" için, öğrenmeniz gereken bazı şeyleri es geçmiş sayılıyorsunuz. Fakat bunların sonradan önünüze çıkma ihtimali oluyor. Onun için sürekli yeni şeyler öğrenerek kendini geliştirmenin ötesinde, bunun ayrımını zamanla ve ihtiyaç olduğunda yapabilmek bence çok daha önemli. Niye kullandığınızı bilmeseniz bile bu fonksiyonları her sorun için en doğru çözüm olduğunu düşünerek onları her sorunda uygulayacak şekilde aynı pakette birleştirmeli ve her sorunda bunları kullanmalısınız.

Bilmemne dilinin bilmemne framework'ü muhteşem(!)🤭

Bir dil, bir framework, bir teknoloji adına ne derseniz deyin bağımlısı olmak anlamsız ama gerçekten bildiğinizi düşündüğünüz bir dil tabii şart. Bazı diller bazı çözümlere yoğunlaştıları için o konuda gelişmiş yapılar hatta veri tipleri dahi barındırır. Ancak bildiğiniz dil sayısıyla övünmek yalnız konuşma dillerinde işe yarar. Çünkü CPU denen işlem birimi sadece makine kodundan anlar ve siz onunla arada bir tercüman olmadan birebir konuşacaksanız o zaman zaten en düşük seviye programlama dillerine doğru yönelmeniz gerekir. Özellikle son yıllarda CIL, JWM, interpreter benzeri 'tercümanlar'  bu ihtiyacı bir nevi soyutlamıştır. Dil bu şekilde soyutlanınca modellemenin soyutlanmasına da daha fazla yük binmiştir ve asıl mesele bu modellemeyi düzgün bir şekilde kurgulayabilmektedir. İhtiyacı verimli şekilde karşıladıkça bir dil yeterlidir, iyi ya da kötü tarafları muhakkak vurgulanabilir, paylaşılabilir ama ateşli savunucusu olmak gereksiz. Yeterli gelmediği durumda eskide kalıyor; dolayısıyla sizi de eskide bırakıyor demektir. Kısacası, illa bağımlısı olunacaksa yaklaşımların, prensiplerin bağımlısı olunabilir; hatta özellikle olunmalıdır. Bu yazıyı yazmamdaki temel amaç tam olarak bu. Yazılım dünyasının uzun yıllar içinde edindiği bu prensipleri doğru şekilleri ile kullanabiliyor olmak.

Ancak prensipler daha spesifik bir konu olduğu için basit bir örnek olması açısından programcılığın en basit konusu olan karar yapılarını ele alalım. Bir if-else bloğu yazarken 2 durumu karşılaştırırsınız. Bu yapıyı öğrenirken aslında yazılım diye öğretilen ama yüzyıllar öncesinde bulunan mantık biliminin sadece küçücük bir parçasından bir kesit öğrenirsiniz. Yani 2 satırlık if-else önermeniz dahi özdeş ve çelişmez olmalıdır; aksi takdirde ya zaten derlenmez ya çalışma zamanında hata fırlatır ya da hiçbir hata vermeden programınızda mantıksal hatalara yol açar ki en tehlikelisi budur. Bunları önlemenin yolu da bizi, mantığın bir kolu olduğunu düşündüğüm algoritmaya götürür. Eğer buraya kadar okuduysanız, aslında çok zorda kalmadıkça kafa karıştırıcı teknik açıklamalar kullanmaktan kaçındığım özellikle dikkatinizi çekmiştir. Haliyle algoritmayı da zaten bilimsel terimleri ile binlerce kaynaktan bulabilirainiz; o yüzden burada tanımından bahsetmeyeceğim ama şunu özellikle belirtmek istiyorum. İlk defa duysanız bile aslında algoritmanın ne olduğunu biliyorsunuz. Çok ciddiyim, şu an bu yazıyı okurken dahi "algoritma motorunuz" zaten çalışıyor. Bu kısma gelene kadar açıkladıklarıma belki hak verdiniz, belki saçma buldunuz. İşte bunun kararını size verdiren, şu an seçeneği düşünürken beyninizin size verdirdiği kararların bütününe algoritma diyoruz. Bu motor sık sık çalıştırılarak ve arada yüksek devirlerde zorlanarak gelişir, mümkün olduğunca çok çalıştırmalı ve arada gazı köklemelisiniz.🥴

Sonuç olarak, şahsen önerilerim:

  • Programlama diliyle ya da ondan bağımsız olarak salt 'algoritma motorunuzu' olabildiğince işler hale getirin.
  • Programlamanın tamamen dışında, kafanızı rahatlatacak -mümkünse tamamen ilkel- bir şeyler bulun.
  • Çok kesin bir plan yapmayın ama bir teknoloji, bir framework, bir prensip, bir kütüphane veya metodoloji ne olursa olsun adım adım gidin. Derede yüzmeden okyanusta boğulmayın!
  • Şu dil ile başlamam gerek gibi bir saplantıya kapılmayın. Modern dillerden biriyle başlayıp önce temelleri öğrenin.
  • En saçma kodunuz olacak bile olsa mutlaka kendiniz deneyin.
  • Aslında karmaşıklığı bilinen bir şeyi çok basit diye nitelendiriyor ve böyle uyguluyorsanız muhtemelen onu bilmiyor veya yanlış biliyorsunuzdur. Şu sözdekine kıyasla yaptığımız iş hava civa tabii ama ana fikri yakalayın: "Kuantum fiziğini anladığınızı düşünüyorsanız, kuantum fiziğini anlamamışsınızdır.” Richard Feynman
  • Bence en önemlisi ki özellikle sona bıraktım ve bir açıklama yazmayacağım; şu muhteşem söz : "Bir insanın zekası, verdiği cevaplardan değil; soracağı sorulardan anlaşılır" Albert Einstein

Buraya kadar atlamadan okuduysanız düşünme şeklinizi geliştirmeyi araya yerleştirdiğim yanlış cümleyi bulmakla başlayın😉


What is software development?

SOLID Principles

Design Patterns