Modern Yazılım Mühendisliği Kitabı
Merhaba, size güzel bir kitaptan daha bahsetmek istiyorum.
Kitaba şuradan ulaşabilirsiniz.
Mühendislik — Bilimin Pratik Uygulaması
Yazılım geliştirme, bir keşif ve araştırma sürecidir; bu nedenle, onda başarılı olmak için yazılım mühendislerinin öğrenme konusunda uzman olmaları gerekir.
İnsanlığın öğrenmeye en iyi yaklaşımı bilimdir, bu yüzden bilimin tekniklerini ve stratejilerini benimsemeli ve bunları sorunlarımıza uygulamalıyız. Bu genellikle, yazılım bağlamından bakarsak, kesinlik düzeylerini mantıksız olarak ölçen fizikçiler olmamız gerektiği gibi yanlış bir anlama yol açabilir. Mühendislik bundan daha pragmatiktir(faydacı).
Bilimin tekniklerini ve stratejilerini uygulamamız gerektiğini söylediğimde kastettiğim, bazı basit ama yine de son derece önemli fikirleri uygulamamız gerektiğidir.
Çoğumuzun okulda öğrendiği bilimsel yöntem, Wikipedia tarafından şu şekilde açıklanmaktadır:
- Karakterize et: Mevcut durumun bir gözlemini yapın.
- Hipotez kur: Bir açıklama, gözleminizi açıklayabilecek bir teori oluşturun.
- Tahmin et: Hipotezinize dayalı bir tahmin yapın.
- Deney yap: Tahmininizi test edin.
Düşüncemizi bu şekilde düzenlediğimizde ve birçok küçük deney temelinde ilerleme kaydetmeye başladığımızda, uygunsuz sonuçları eleyerek daha iyi bir iş çıkarmaya başlarız.
Sonuçlarımızda daha fazla tutarlılık ve güvenilirlik elde edebilmek için, deneylerimizdeki değişkenleri kontrol etmeyi düşünmeye başlarsak, bu bizi daha deterministik(kararlı) sistemler ve kodlara doğru yönlendirir. Fikirlerimiz hakkında şüpheci olmaya başlarsak ve onları nasıl tahrif edebileceğimizi araştırırsak, kötü fikirleri daha çabuk tespit edip ortadan kaldırabilir ve böylece çok daha hızlı ilerleme kaydedebiliriz.
Bu kitap, temel bilimsel ilkelerin, diğer bir deyişle mühendisliğin gayri resmi olarak benimsenmesine dayanan, yazılımdaki sorunları çözmeye yönelik pratik, pragmatik bir yaklaşıma dayanmaktadır!
Yazılım Mühendisliği Nedir?
Yazılım mühendisliği, yazılımdaki pratik sorunlara verimli, ekonomik çözümler bulmaya yönelik deneysel, bilimsel bir yaklaşımın uygulanmasıdır.
Yazılım geliştirmeye mühendislik yaklaşımının benimsenmesi iki ana nedenden dolayı önemlidir. Birincisi, yazılım geliştirme her zaman bir keşif ve öğrenme alıştırmasıdır ve ikincisi, amacımız “verimli” ve “ekonomik” olmaksa, o zaman öğrenme yeteneğimiz, sürdürülebilir olmalıdır.
Bu, yarattığımız sistemlerin karmaşıklığını, yeni şeyler öğrenme ve bunlara uyum sağlama yeteneğimizi sürdürecek şekilde, yönetmemiz gerektiği anlamına gelir.
Bu nedenle, öğrenmede ve karmaşıklığı yönetmede uzman olmalıyız.
Öğrenmede odaklanmanın köklerini oluşturan beş teknik vardır. Özellikle, öğrenmede uzman olmak için aşağıdakilere ihtiyacımız vardır:
• Yineleme
• Geri bildirim
• Artımsal ilerleme
• Deneycilik
• Deneyimcilik
Bu, karmaşık sistemlerin yaratılmasına yönelik evrimsel bir yaklaşımdır. Karmaşık sistemler, bizim tamamen hayal gücümüzden oluşmaz. Fikirlerimizi denediğimiz ve yol boyunca başarıya ve başarısızlığa tepki verdiğimiz birçok küçük adımın ürünüdürler. Bunlar, bu keşfi gerçekleştirmemize izin veren araçlardır.
Bu şekilde çalışmak, güvenli bir şekilde nasıl ilerleyebileceğimize dair kısıtlamalar getirir. Her yazılım projesinin kalbinde yer alan, keşif yolculuğunu kolaylaştıracak şekilde çalışabilmemiz gerekiyor.
Bu nedenle, öğrenmeye lazer-odaklı odaklanmanın yanı sıra, yanıtlar ve hatta bazen yönün belirsiz olduğu durumlarda bile ilerleme kaydetmemizi sağlayacak şekillerde çalışmamız gerekir.
Bunun için karmaşıklığı yönetme konusunda uzman olmamız gerekiyor. Çözdüğümüz sorunların doğası veya bunları çözmek için kullandığımız teknolojiler ne olursa olsun, karşılaştığımız sorunların karmaşıklığını ve bunlara uyguladığımız çözümleri ele almak, kötü sistemler ile iyi sistemler arasındaki temel farkı ortaya çıkarır.
Karmaşıklığı yönetmede uzman olmak için aşağıdakilere ihtiyacımız vardır:
• Modülerlik(Modularity)
• İç Bağlılık(Cohesion)
• İlgilerin Ayrıştırılması(Separation of Concerns)
• Soyutlama(Abstraction)
• Gevşek Bağlılık(Louse Coupling)
Bu fikirlere bakmak ve onları tanıdık görüp reddetmek kolaydır. Bu kitabın amacı, onları organize etmek ve potansiyellerinden en iyi şekilde yararlanmanıza yardımcı olacak yazılım sistemleri geliştirmeye yönelik, tutarlı bir yaklaşım içine yerleştirmektir.
Bu kitap, bu on fikrin yazılım geliştirmeyi yönlendirmek için araçlar olarak nasıl kullanılacağını açıklar. Ardından, herhangi bir yazılım geliştirme için ve etkili bir strateji yürütmek için pratik araçlar halinde hareket eden bir dizi fikri, tarif etmeye devam eder. Bu fikirler aşağıdakileri içerir:
• Test edilebilirlik
• Dağıtılabilirlik(Deployability)
• Hız
• Değişkenleri kontrol etme
• Sürekli dağıtım(Continuous delivery)
Bu düşünceyi uyguladığımızda, sonuçları çok derin olur. Daha kaliteli yazılımlar üretiriz, daha hızlı iş üretiriz ve bu ilkeleri benimseyen ekiplerde çalışan kişiler, işlerinden daha çok keyif aldıklarını, daha az stres hissettiklerini ve daha iyi bir iş-yaşam dengesine sahip olduklarını bildiriyorlar.
Bunlar abartılı iddialar olsa da, verilerle desteklenen iddialardır.
“Yazılım Mühendisliğini” Geri Kazanmak
Bu kitabın başlığı üzerinde çok uğraştım, çünkü ona ne ad vermek istediğimi bilmiyordum, ama endüstrimiz, mühendisliğin yazılım bağlamında ne anlama geldiğini o kadar çok yeniden tanımladı ki, terimin anlamı değersizleşti.
Yazılımda genellikle ya basitçe “kod” ile eşanlamlı olarak ya da insanları aşırı bürokratik ve prosedürel olarak erteleyen bir şey olarak görülür. Gerçek mühendislik için hiçbir şey, gerçeklerden daha uzak olamaz.
Diğer disiplinlerde mühendislik, basitçe “işe yarayan şeyler” anlamına gelir. İyi bir iş çıkarma şansınızı artırmak için, başvurduğunuz süreç ve uygulamadır.
“Yazılım mühendisliği” uygulamalarımız, daha iyi yazılımları daha hızlı oluşturmamıza izin vermiyorsa, o zaman gerçekten mühendislik değillerdir ve onları değiştirmeliyiz!
Bu kitabın kalbindeki temel fikir budur ve amacı, tüm büyük yazılım geliştirmenin temelinde yer alan, bazı temel ilkeleri bir araya getiren, entelektüel açıdan tutarlı bir modeli tanımlamaktır.
Başarının asla bir garantisi yoktur, ancak bu zihinsel araçları benimseyerek ve ilkeleri organize ederek ve bunları işinize uygulayarak başarı şansınızı kesinlikle artıracağınızdan eminim.
İlerleme Nasıl Yapılır?
Yazılım geliştirme, karmaşık bir faaliyettir. Bazı açılardan, bir tür olarak üstlendiğimiz en karmaşık faaliyetlerden biridir. Bunun yanında her yeni bir işe başladığımızda, her bireyin ve ekibin sıfırdan ona nasıl yaklaşılacağını icat edebileceğini ve icat etmesi gerektiğini varsaymak komik olur.
İşe yarayan veya yaramayan şeyleri öğrendik ve öğrenmeye devam ediyoruz. Peki, Isaac Newton’un bir zamanlar dediği gibi, “herkesin her şey üzerinde veto hakkı varsa”, sektör ve ekipler olarak nasıl ilerleme kaydedebiliriz? Bu yüzden, üzerinde anlaşmaya varılmış ilkelere ve faaliyetlerimizi yönlendiren bir disipline ihtiyacımız bulunur. Bu düşünce tarzındaki tehlike ise, eğer yanlış uygulanırsa, acımasız, aşırı yönlendirici, “otoriteden gelen karar” tarzı düşünmeye yol açabilmesidir. Yöneticilerin ve liderlerin işinin başkalarına ne yapacaklarını ve nasıl yapacaklarını söylemek olduğu varsayılan önceki kötü fikirlere geri dönmüş oluruz.
“Yasaklayıcı” veya aşırı “yönlendirici” olmanın en büyük sorunu şudur: Bazı fikirlerimiz yanlış veya eksikse ne yaparız? Kaçınılmaz olarak öyle olacaklar, öyleyse eski, ancak iyi kurulmuş, kötü fikirlere nasıl meydan okuyabilir ve onları nasıl çürütebiliriz. Yeni, potansiyel olarak harika, denenmemiş fikirleri nasıl değerlendirebiliriz?
Bu sorunların nasıl çözüleceğine dair çok güçlü bir örneğimiz var. Bu bize, dogmaya meydan okuma, çürütme fırsatı verir. Moda olsa bile kötü fikirlerin ne olursa olsun harika fikirler ile arasında ayrım yapma konusunda, bize entelektüel özgürlük sağlayan bir yaklaşımdır. Kötü fikirleri daha iyi fikirlerle değiştirmemizi ve iyi fikirleri geliştirmemizi sağlar. Biz buna iyi örnek bilim diyoruz!
Bu tür bir düşünceyi, pratik problemleri çözmek için uyguladığımızda buna mühendislik diyoruz!
Bu kitap, bilimsel tarzda akıl yürütmeyi disiplinli bir şekilde uygulamak ve böylece gerçekten ve doğru bir şekilde yazılım mühendisliği olarak adlandırabileceğimiz bir şeyi başarmanın ne anlama geldiğini bilmek hakkındadır.
Yazılım Mühendisliğinin Doğuşu
Bir kavram olarak yazılım mühendisliği 1960'ların sonunda oluşturuldu. Terim ilk olarak, daha sonra MIT Enstrümantasyon Laboratuvarı’nın Yazılım Mühendisliği Bölümünün direktörü olan Margaret Hamilton tarafından kullanıldı. Margaret, Apollo uzay programı için uçuş kontrol yazılımını geliştirme çabalarına öncülük ediyordu.
Aynı dönemde, Kuzey Atlantik Antlaşması Örgütü (NATO), terimi tanımlamaya çalışmak için Almanya’da bir konferans düzenledi. Bu ilk yazılım mühendisliği konferansıydı.
En eski bilgisayarlar, anahtarları çevirerek programlanmış, hatta tasarımlarının bir parçası olarak sabit kodlanmışlardı. Öncüler için bunun yavaş ve esnek olmadığı çabucak anlaşıldı ve “depolanmış program” fikri böylece doğdu. Bu, yazılım ve donanım arasında ilk kez net bir ayrım yapan fikir idi.
1960'ların sonunda, bilgisayar programları, kendi başlarına oluşturulması ve sürdürülmesi zor olacak kadar karmaşık hale geldi. Daha karmaşık problemlerin çözümüne dahil oldular ve hızla belirli problem sınıflarının çözülmesine izin veren kolaylaştırıcı adımlar haline geldiler.
Donanımda ilerleme hızı ile yazılımda ilerleme hızı arasında önemli bir fark olduğu algılandı. Bu, o zamanlar yazılım krizi olarak anılırdı.
NATO konferansı, kısmen bu krize yanıt olarak toplandı.
Bugün, konferanstan notları okurken, açıkça kalıcı olan birçok fikir var olduğunu görürüz. Zamanın yıkıcılığına direndiler ve 1968'de olduğu gibi bugün de doğru olmaya devam ediyorlar. Disiplinimizi tanımlayan bazı temel özellikleri belirlemeyi arzuluyorsak, bu bizim için ilginç olmalı.
Birkaç yıl sonra geriye dönüp bakıldığında, Turing ödüllü Fred Brooks(1986, “No Silver Bullet.”) yazılımdaki ilerlemeyi donanımdaki ilerlemeyle karşılaştırdı:
“ Üretkenlikte, güvenilirlikte, basitlikte on yıl içinde tek başına bir büyüklük artışı vaat eden ne teknolojide ne de yönetim tekniğinde tek bir gelişme yoktur.”
Brooks bunu, donanım geliştirmenin yıllardır takip ettiği ünlü Moore yasasına kıyasla söylüyordu. Accelerate(2018) kitabında şöyle deniliyordu:
“1965'te Gordon Moore, transistör yoğunluklarının her yıl iki katına çıkacağını ve sonraki on yıl boyunca (1975'e kadar) her iki yılda bir revize edileceğini öngördü. Bu tahmin, yarı iletken üreticileri için bir hedef haline geldi ve Moore’un beklentilerini önemli ölçüde aştı ve birkaç on yıl daha karşılandı. Bazı gözlemciler, mevcut yaklaşımların sınırlamaları ve kuantum etkileri yaklaşımı nedeniyle kapasitedeki bu patlayıcı büyümenin sonuna ulaştığımıza inanıyor, ancak bu yazının yazıldığı sırada, yüksek yoğunluklu yarı iletken geliştirme Moore yasasını takip etmeye devam ediyor.”
Bu ilginç bir gözlem ve bence birçok insanı şaşırtacak ama özünde her zaman doğru olan bir durumdu.
Brooks, bunun bir yazılım geliştirme sorunu olmadığını; donanım performansındaki benzersiz, şaşırtıcı gelişme üzerine bir gözlem olduğunu belirtiyordu:
“Anomali, yazılım ilerlemesinin çok yavaş olması değil, bilgisayar donanımının çok hızlı ilerlemesi olduğunu gözlemlemeliyiz. Medeniyet başladığından beri başka hiçbir teknoloji 30 yılda altı kat fiyat-performans artışı göstermedi.”
Bunu, bugün bilgisayar çağının şafağı olarak düşündüğümüz şeyi ta o zaman 1986'da yazdı. O zamandan beri donanımdaki ilerleme bu hızla devam etti ve Brooks’a çok güçlü görünen bilgisayarlar, modern sistemlerin kapasitesi ve performansıyla karşılaştırıldığında oyuncak gibi görünüyordu. Ve yine, yazılım geliştirmedeki gelişme oranı hakkındaki gözlemi doğru olmaya devam ediyor.
Paradigmayı Değiştirmek
Paradigma kayması fikri, fizikçi Thomas Kuhn tarafından yaratıldı.
Çoğu öğrenme bir tür birikimdir. Her bir katmanın temel olarak bir öncekiyle desteklendiği, anlayış katmanları oluştururuz. Ancak, tüm öğrenme böyle değildir. Bazen bir şeye bakış açımızı kökten değiştiririz ve bu yeni şeyler öğrenmemizi sağlar, ancak bu aynı zamanda daha önce olanları atmamız gerektiği anlamına gelir.
Paradigma değişimi fikri, örtük olarak, böyle bir değişiklik yaptığımızda, bu sürecin bir parçası olarak, artık doğru olmadığını bildiğimiz bazı diğer fikirleri atacağımız fikrini içerir.
Yazılım geliştirmeyi, bilimsel yöntem ve bilimsel rasyonalizm felsefesine dayanan gerçek bir mühendislik disiplini olarak ele almanın sonuçları çok derindir.
Bu bize daha etkili bir şekilde öğrenme ve kötü fikirleri daha verimli bir şekilde atma konusunda bir yaklaşım sağlar.
Bu kitapta anlattığım yazılım geliştirme yaklaşımının böyle bir paradigma değişimini temsil ettiğine inanıyorum. Ne yaptığımız ve nasıl yaptığımız konusunda bize yeni bir bakış açısı sağlayacağını düşünüyorum.
2. Mühendislik Nedir?
…