← Computers & Automation

Software Development Systems

B
Bilinmeyen Yazar
1987 · Computers and Automation

Yazılım Geliştirme Sistemleri

Peter Freeman
Bilgisayar Bilimleri Profesörü
University of California
Irvine, CA 92777

Bölüm 2

“Dünyamızın gerçeklerini ve kavramlarını anlarsak, belirli bir eylem standardı dayatan bazı ilkeleri ya da davranış kurallarını formüle edebilecek konuma geliriz.”

Alan Bilgisini İfade Etmek İçin Yeni Diller

Bir uygulama hakkında büyük miktarda bilgi içeren, son derece özelleşmiş bazı dilleri görmeye başlıyoruz. Belirli bir ekipmanın kontrolüne yönelik diller bu türdendir; aynı şekilde, belirli bir uygulamanın temelindeki bir modele dayanan program üretici paketler de buna dahildir.

Bu diller şu anda toplam uygulama yelpazesinin yalnızca çok küçük bir bölümünü kapsamaktadır; ancak uygulamaya özgü dillerin üretilmesini kolaylaştırmak için araştırmalar sürmektedir.

Yazılım mühendisliği bilgisi ile alan-özgül bilgi arasında daha da küçük bir kesişim vardır. Yazılım mühendisliğinde, belirli bir türdeki uygulamaların nasıl geliştirileceğini doğrudan ele alan çok az ilkeye sahibiz (örneğin, otel kayıt sistemleri).

Bir ölçüde bu kabul edilebilir; çünkü tüm uygulama sınıflarını kapsayan bazı özgüllüklerimiz vardır (örneğin, gerçek zamanlı sistemler ya da veritabanı sistemleri). Ancak bu bilgi, şu anda son derece yetersizdir.

Tahmin edebileceğiniz gibi, geliştirme bilgisi sınıfları arasındaki en küçük örtüşme, her sınıfta belirli bir sistemle ilgili bilgiyi bulmaya çalıştığımızda ortaya çıkar. Bu kesişim, yazılımın başarılı bir biçimde oluşturulması için kesinlikle kritiktir; çünkü kavramsal olarak istenen sistemi meydana getirmek için gerekli tüm bilgileri içerir.

Bu durumun bazı stratejik sonuçları vardır. Alan bilgisini ve/veya yazılım mühendisliği bilgisini daha iyi kullanmamıza yardımcı olmayan yazılım temsillerinin (yeni dillerin) geliştirilmesi, saf araştırma alanına girer—yani dil tasarım ilkelerinin sonuçlarını kendi başlarına keşfetmeyi amaçlar.

Bu, uzun vadede oldukça önemlidir ve kesinlikle desteklenmelidir. Ancak, daha kısa vadeli kazanımlar elde etmek için, şu anda sahip olduğumuz alan ve geliştirme bilgisini daha iyi kullanmaya yardımcı olabilecek yeni dillere odaklanmanın en iyi yaklaşım olabileceğini kabul etmek önemlidir.

Bilginin Denetimi

Bilginin denetimi, geliştirmenin denetiminin merkezindedir—ve temsil, bilginin denetiminin merkezindedir.

Pragmatik yazılım geliştirme açısından, geliştirme ortamındaki farklı bilgi biçimleri arasındaki dengenin yönetilmesi önemlidir.

Yazılım mühendisliği becerileri bakımından güçlü, ancak alan-özgül (uygulama) bilgiye etkili erişimi olmayan bir grup, müşterilerin ihtiyaç duyduğu sistemleri geliştirmekte büyük zorluk yaşayacaktır.

Öte yandan, bir uygulama alanını çok iyi anlayan ancak yazılım mühendisliği bilgi birikimi yetersiz olan bir grup, oluşturmaya çalıştıkları yazılımın karmaşıklığı içinde batma tehlikesiyle karşı karşıya kalır.

Her ikisinin temelinde, sürecin genel olarak yönetilebilmesi için bilginin etkili biçimlerde temsil edilmesine duyulan gereksinim yatar.

Bilgi, yazılımın özüdür. Doğru şekilde yönetilmezse, hızla karmaşık hale gelir ve kaybolur; bunun yazılım üzerindeki etkisi öngörülebilirdir.

Gerçekte bu sıkça olur. Durum, 100 yıl önceki hastanelerdekine benzer. Çeşitli mikroorganizmaların rolü hakkında keşifler yapıldıkça, insanların hastanelerde yaptıkları birçok şeyin çok tehlikeli olduğu fark edildi; bunun sonucunda, daha önce göz ardı edilen uygulamalara (örneğin aletlerin sterilizasyonu) birdenbire büyük önem verildi.

Yürütülebilir yazılım üretme süreci üzerindeki pek çok tür bilginin rolünü daha tam olarak takdir etmeye yeni yeni başlıyoruz ve bu nedenle ona daha fazla saygı göstermeye başlıyoruz.

Şu anda, geliştirme bilgisinin ele alınmasında doğallık ile biçimsellik arasında zayıf bir denge vardır. Birçok teknik personel yalnızca yazılımın yürütülebilir biçimlerine odaklanmakta, bu da sorunlara yol açmaktadır.

Örneğin, bir yazılım parçasının yapısal yönleri hakkında pek çok değerli bilgi geliştirme sırasında kaybolur. Başlangıçta bu bir sorun teşkil etmeyebilir; ancak zamanla genellikle sorun olur, çünkü bu bilgi tam da yazılım evrim geçirirken (genellikle bakım olarak adlandırılır; ancak üç tür değişikliği kapsar: onarım, uyarlama ve iyileştirme) bütünlüğünü korumaya yardımcı olmak için gereken bilgidir.

Bu, kendini departmanlara ayıran ve ardından hangi çalışanların hangi departmanlara ait olduğuna dair tüm bilgileri kaybeden bir kuruluşa benzer; yeniden yapılanma çok zor olacaktır.

Belady ve Lehman, öncü çalışmalarında, yapısal bilginin (modüller gibi alt birimlerin tanımı ve aralarındaki arayüzler) bir yazılım sisteminin zaman içinde değişim geçirirken teknik ve yönetsel denetiminin sürdürülmesi için vazgeçilmez olduğunu bulmuşlardır.

Adlarında “yapı” geçen bir dizi tekniğe (programlama, tasarım, analiz, test) rağmen, ilk geliştirmeden sonra sistemin iç yapısına ilişkin tutarlı bir kaydın tutulmadığı durumlara hâlâ sıkça rastlanmaktadır.

Öte yandan yönetim, bunun tümüyle teknik bir bilgi olduğunu ve teknisyenlere bırakılması gerektiğini çoğu zaman varsayar; yine, müşterinin belirli bir özelliği neden talep ettiğine dair gerekçeler gibi yönetim için değerli bilgiler kaybolabilir. Bilginin öneminin fark edilmesinden sonra verilen tepki bazen her şeyin saklanmasını zorunlu kılmak olur—bu da evrak yüklü, son derece “biçimsel” bir sisteme ve buna eşlik eden sorunlara yol açar.

Geliştirme ortamındaki bilgiye karşı daha gevşek ve sezgisel olmaya çalışmalı, ancak bununla birlikte ilgili kısımlarını kullanılabilir biçimde korumalıyız. Şimdilik ise, hangi bilginin en önemli olduğunu hâlâ keşfederken ve onunla nasıl başa çıkacağımızı öğrenirken, daha açık ve belirgin olmak zorundayız.

Bu amaçla, yazılıma genel anlamda bakalım ve zaman içinde ona ne olduğunu görelim.

Yazılımın Biçimleri

Muhtemelen yazılımın aldığı birçok biçime, en azından kabaca, aşinasınızdır:

  • Makine dilinde programlar
  • Üst düzey dillerde programlar
  • Şartnameler
  • İhtiyaç bildirimleri
  • Gereksinimler
  • Mimari tasarımlar
  • Ayrıntılı tasarımlar
  • Veri biçimleri
  • Program koleksiyonları
  • Test edilen programlar
  • Tamamlanmış programlar
  • Üretimde kullanılan sistemler

ayrıca “yazılım” genel terimi altında topladığım diğer bazı bilgi biçimleri de vardır:

  • Gereksinim analizleri
  • Kullanıcı dokümantasyonu
  • Bakım dokümantasyonu
  • Değişiklik talepleri
  • Değişiklik şartnameleri
  • Hata raporları
  • Performans ölçümleri

ve benzerleri!

Yazılımın biçimlerini tartışmaya başladığımda sıklıkla birkaç tepkiden biriyle karşılaşırım:

Teknik geliştirme sürecine derinlemesine dahil olanlar, bu unsurlardan bazılarının kendi tanımlarını savunmak ister; bu sürece çok dahil olmayanlar, her bir biçimin açık bir tanımının verilmesini ve hangilerini kullanmaları gerektiğinin söylenmesini ister; dahil olup da teknik geliştirmede doğrudan yer almayan bazıları ise hiç umursamaz ve kritik olduğunu düşündükleri konuların ele alınmasına geçmek ister. Bu, bir seçimi analiz etmeye benzer; herkesin farklı bir bakış açısı vardır.

Bu bakış açılarının tümü anlaşılabilirdir ve kendi bağlamlarında uygundur.

İyi yazılım geliştirmenin temel ilkelerini daha iyi anlamanızı sağlamak amacıyla farklı bir bakış açısını teşvik etmek istiyorum: geliştirme sürecini izleyen ve yazılım adı verilen bu kaygan maddenin, bir fikirden üretim sistemine uzanan yolculuğu sırasında hangi biçimleri aldığını görmeye çalışan bir gözlemcinin bakış açısı.

Bu bakış açısı, yazılım geliştirilirken izlenen farklı adım dizilerinin göreli değerleri hakkında çok hızlı biçimde tartışmalara yol açabilir (genellikle hangi yaşam döngüsünün en iyi olduğu tartışmaları olarak adlandırılır). Buna daha sonra geri döneceğiz; ancak yine de, ele aldığımız şeyin temel doğasını biraz daha iyi anlayana kadar belirli yaklaşımlar hakkındaki tartışmaları erteleyelim.

Yazılımın Yaşam Döngüsü

Yaşam döngüsü kavramı, yazılım dünyasında, yazılımın geçtiği aşamaları belirtmek için benimsenmiştir. Terimi ödünç aldığımız biyolojide olduğu gibi, yürütülebilir bir yazılım parçası, canlının doğası tarafından (ve bir ölçüde, bitmiş ürünü meydana getirmek için sahip olduğumuz teknikler tarafından) az çok belirlenen bir dizi aşamadan geçer.

Kabaca, yazılım aşağıdaki aşamalardan geçer:

  • Kavram geliştirme (tanımlama)
  • Teknik oluşturma (geliştirme)
  • Kullanıma yönelik ürün (işletim)
  • Daha ileri geliştirme nesnesi (evrim)

Kullanılan yöntemler, araçlar ve teknikler bu temel, baskın dizilim üzerinde çok az etkiye sahiptir. Sistemin ne yapacağına dair bir fikirle başlamak zorundayız; ardından onu oluştururuz, kullanırız ve büyük olasılıkla değiştiririz. Yazılımın her biçiminde, istenen davranışı elde etmek için bir donanıma yüklenecek olan nihai nesnenin bir temsili bulunur.

Bu temel dizilimin son derece önemli olabilecek varyasyonları olduğunu anlamak önemlidir. Nasıl ki çocuklar öğrenebilmek için sınırlı yetişkin etkinliklerine katılırlarsa, yazılımın da geliştirilirken bazı işletimsel zorlanmalara maruz bırakılması, nihai “yetişkinliğine” dayanıp dayanamayacağını mümkün olan en erken anda öğrenebilmemiz açısından çoğu zaman kritik öneme sahiptir.

Artık yazılım geliştirmenin her zaman tamamen katı bir ilerleme izleyemeyeceğini, bunun yerine aşamalar arasında yinelemeli bir biçimde döngü yapması gerekebileceğini daha net anlıyoruz. Örneğin yazılım prototipleme, bu temel kavramın bir ifadesidir.

Bu noktada, yazılımın teknik tasarımında olduğu gibi bazen son noktaya çok hızlı ilerlememenin faydalı olduğunu bildiğim için (bunun bazılarınız için sinir bozucu olduğunu biliyorum), yazılımın doğasına ilişkin geniş bir perspektif sunabilmek adına aşırı özgül olmaktan kaçınmaya çalışıyorum.

Aşağıdaki yazılım biçimleri tanımının (örneklerle birlikte) yararlı olduğunu düşünüyorum:

1. Geliştirme Prologları

  • İhtiyaç bildirimleri
  • İhtiyaç analizleri
  • Gereksinim bildirimleri
  • Gereksinim analizleri
  • Veri öğesi tanımları
  • İşlevsel şartnameler

2. Teknik Sistem Tanımları

  • Teknik şartnameler
  • Mimari tasarımlar
  • Ayrıntılı tasarımlar
  • Veritabanı yapıları
  • Veri tanımları
  • Yürütülebilir programlar

3. Sistem Bileşimleri

  • Program koleksiyonları
  • Program sistemleri
  • Arayüz tanımları
  • Tümleşik donanım/yazılım sistemleri
  • Tümleşik insan/donanım/yazılım sistemleri

4. Kurulu Sistemler

  • Referans (temel) sistemler
  • Sürümler
  • Üretim sistemleri

5. Performans Verileri

  • Verimlilik ölçümleri
  • Hata raporları
  • Etkililik derecelendirmeleri
  • Kullanıcı derecelendirmeleri

Tekrar edeyim: buradaki amacım yazılım yapıtlarının mutlak, teknik açıdan kusursuz tanımlarını vermek değildir. Bunun yerine, etrafınızda neler olup bittiğine dair bir perspektif kazanmanıza yardımcı olacak bazı soyutlamalar sunmaya çalışıyorum.

Bu kategorilerin her birine kısaca bakalım.

Geliştirme Prologları

Yazılımın teknik geliştirilmesinden önce bir şeylerin geldiği açıktır—yöneticiden gelen bir not, bir peçetenin arkasına çizilmiş bir uygulama fikri, bir sistemde ihtiyaç duyulan işlevlerin ayrıntılı bir ifadesi, ihtiyaçların ve belirtilmiş gereksinimlerin analizi vb.

Bu bilginin genel niteliği, sistemin işlevselliğine, belirli bir araçsal ortamda kullanımına, diğer sistemlerle ilişkisine odaklanmasıdır—kısacası, altta yatan fiziksel donanımdan uzak durur. (Geliştirmede yolunda gitmeyen şeylerden biri, sistemin dış yönlerine dair net bir anlayış kazanılmadan önce teknik tanımların bazen bu tür bilgilerle karıştırılmasıdır.)

Bunu “geliştirme prologları” olarak adlandırdım; çünkü teknik geliştirmeden önce gelen bilgiyi vurgulamak istiyorum. Yine de, bunların tümünde nihai sistemin bazı yönlerini görmek mümkündür. Geliştirme prologları, yeni bir yasanın kabulü gibi bir hükümet eyleminden önce gelen başyazılar, konuşmalar ve makaleler gibidir.

Teknik Sistem Tanımları

“Teknik sistem tanımları”, tasarımcıların ofislerinde, programcıların masalarında bulunan, kara tahtalara (ya da programcıların favorisi olan, kolay renklendirme gibi ek bir boyut sunan beyaz tahtalara) karalanmış tanıdık yapıtları içerir.

Bu sınıfı anlamakta büyük bir zorluk olmamalıdır. Şartnameler alanında, pratikte geliştirme prologları ile teknik tanımlar arasında var olan örtüşmeye dikkat etmekte fayda vardır. Nitekim iyi bir şartname kümesi, dışa dönük geliştirme prologları ile içe dönük teknik tanımlar arasında tam anlamıyla bir köprüdür; çünkü her ikisi olarak da değerlendirilebilir.

Benzetmeyi sürdürürsek, teknik sistem tanımları yasalar ve yönetmeliklerdir.

Sistem Bileşimleri

"Sistem toplamları" da elbette teknik yapıtlar arasındadır; ancak odak noktasındaki değişimi vurgulamak için onları ayrı tuttum. Bireysel bileşenlere (yazılım söz konusu olduğunda çalışan programlara) sahip olduğumuz noktaya kadar, odağımız bu tekil parçalardadır.

Ancak büyük sistemler kurarken, parçalar var olur olmaz mücadele neredeyse yeni başlamış sayılır; çünkü bu parçaları çalışan bir sistem hâline entegre etmemiz gerekir. Bu etkinlik çoğu durumda yalnızca büyük miktarda emek gerektirmekle kalmaz, aynı zamanda temelden farklı kaygılara sahiptir. Bu nedenle, toplamları farklı bir nesne türü olarak ele almanın yararlı olduğunu düşünüyorum.

Bu benzetmede, sistem tanımları belirli bir konuya ilişkin yasa ve yönetmelik koleksiyonlarıdır.

Kurulu Sistemler

Bir sistemi kurup kullanıma hazır hâle getirdiğimizde, odak yeniden değişir; bu nedenle dördüncü bir sistem nesneleri sınıfı gösterdim: "kurulu sistemler." Artık tek tek parçalarla değil, tüm sistemi oluşturan toplamlarla, yani bütün sistemlerle ilgileniriz.

Onları farklı şekilde ele alırız; dolayısıyla yine ayırmak yararlıdır. Kurulu sistemler, fiilen kullanılan ve yorumlanan yasalara karşılık gelir.

Performans Verileri

Gösterdiğim son sınıf olan "performans verileri", muhtemelen kabul edilmesi en zor olanıdır; çünkü bu noktada, en azından yürütülebilir bir sistemin bir bölümünü bir şekilde temsil ettiğini hepimizin kabul edebileceği yapıtların ötesine geçip soyutlamalar alanına girmiş bulunuyorum.

Sistem tanımlarının yerine, bu sınıf kullanım hâlindeki sistemi nitelendiren ölçümleri ve diğer verileri içerir. Benzetmede bunlar, yasanın kullanılmasının sonuçları üzerine toplanan istatistikler ve gözlemlerdir.

Yazılımı Değiştirmek KOLAY DEĞİLDİR!

Yazılımın kalıcı cazibe şarkılarından biri, onu değiştirmenin kolay olduğu mesajıyla bizi cezbetmesidir. Sayısız yönetici ve farkında olmayan programcı suç ortağı, çalışan bir yazılım parçasına bakmış ve onu biraz iyileştirmek ya da başka bir şeye dönüştürmek için kolayca bazı değişiklikler yapabileceklerine inanarak baştan çıkarılmıştır.

Bu görünüşte zararsız ve basit karşılaşmanın ardında yatan acıyı, hayal kırıklığını ve iyi ilişkilerin (örneğin müşterilerle olanların) yıkımını fark etmemişlerdir!

Bu iki yüzlü durum — bir yanda kod satırlarının değiştirilmesinin çok kolay olması, diğer yanda ise sistemlerin başarılı biçimde değiştirilmesinin inanılmaz derecede zor olabilmesi — yazılımın bir sistem olduğu gerçeğinden kaynaklanır.

Bizi bataklığa çeken, tek tek parçalar değil, binlerce iç içe geçmiş bağımlılık ve bağlantıdır.

Modern bir üretim tesisini düşünün. Herkesin ölçütlerine göre karmaşık bir sistemdir; fiziksel tesisler, tedarik teslimatları, enerji, işgücü kuralları ve yüzlerce başka unsurun (hem somut hem soyut) üretken bir ortam meydana getirmek için birlikte düzgün çalışması gerekir.

Buna karşın, bu unsurların neredeyse hiçbiri kolayca değiştirilemez. Enerji sistemleri pahalıdır ve kurulmaları uzun hazırlık süreleri gerektirir; işgücü kurallarının değiştirilmesi yıllar süren pazarlıklar gerektirebilir; belirli parçalar için tedarikçiler kıt olabilir; vb. Sonuç olarak, üretim sistemini değiştirmeye pek hevesli olmayız. (Hatta, bu değişim zorluğunun bazıları tarafından olduğundan daha zor algılanmış olması, belirli endüstrilerin gerilemesini hızlandırmış olabilir.)

Sistemin altında yatan mekanizmalar değişmesi zor olduğu için, sistemik değişikliklere hafifçe girişmeyiz.

Keşke yazılımda daha az esneklik olsaydı!

Gizli İlişkiler

Teknik açıdan, yazılımda bizi mahveden şey öngörülemeyen sonuçlar ve gizli ilişkilerdir. Bir sunumun ekran biçiminde yapılacak küçük bir değişikliğin okunabilirliğini artıracağını düşünürüz (kuşkusuz doğrudur), bu yüzden programlama ekibinden değişikliği yapmasını isteriz (onlar da bunun kodun yalnızca bir modülünde küçük bir değişiklik olduğunu belirtmişlerdir). Değişiklik başarıyla yapılır.

Ne yazık ki, bu değişiklik modül tarafından kullanılan bir tablonun biraz genişletilmesini içerir; bu da sistem boyutunu küçük programlar için zamanlama sınırının üzerine iter. Bunun anlamı, programın artık çok daha yavaş hizmet almasıdır ve sonuç olarak terminaldeki kullanıcıdan gelen isteklere verdiği yanıt süresi neredeyse üç katına çıkar!

Program, telefondayken bir telefonla pazarlama temsilcisini desteklemek için bilgi üretmekte kullanıldığından, sistem artık kullanılamaz hâle gelir.

Ve elbette, değişikliği yapan programcı Cuma akşamı saat 20.00’de işi bitirmiş, belgeleri pazartesiye bırakmaya karar vermiştir; ancak ertesi sabah saat 05.00’te iki haftalık bir vahşi doğa kampı gezisine çıkmıştır.

Böylece, bir programdaki görünüşte küçük bir değişiklik, programın performans özelliklerinde büyük bir değişikliğe yol açmış ve birkaç haftalık üretkenlik kaybına neden olmuştur. Bu, istenmeyen bir tasarım sonucunun oldukça açık bir örneğidir — kolayca görülebilen ve anlaşılabilen bir örnek. Diğerleri bu kadar belirgin değildir.

Tutarlı Kavramsal Temel

Yazılım geliştirirken, diğer pragmatik disiplinlerde sahip olduğumuz türden tutarlı bir kavramsal temele henüz sahip değiliz. Fizik, elektrik ve makine mühendisliğinin temelini oluşturur; sonuçları öngörmemizi ve ilişkileri anlamamızı sağlar. Kimya, kimya mühendisliğinin temelidir. Biyoloji, tıbbı destekler.

Yazılım bütünüyle insan yapımı olduğu ve sonlu ve deterministik makineler (bilgisayarlar) tarafından yorumlandığı için, bilgisayarların altında yatan bilimi nihayetinde anlayabileceğimize ve böylece sonuçlar ve bağlantılarla daha iyi başa çıkabileceğimize inanıyoruz.

Ancak şu anda, beklenen sonuçları yalnızca kısmi bir anlayışla eylemler önermek zorunda kalan tıp doktorlarına (insan vücudunun temel doğasını yalnızca eksik biçimde anlayanlara) çok daha yakınız. Daha da kötüsü, tıp mesleğine kıyasla çok daha az deneyime sahibiz!

Yazılım esnekliğinin cazibe şarkısı, iyi niyetli pek çok profesyoneli baştan çıkarmıştır.

Bağlantılar Ağı

Birçok durumda tasarım sonuçlarını ve sistem bağlarını anlayamıyor olmamız yeterince kötü değilmiş gibi, uzun vadede belki de daha fazla sorun ve masrafa yol açan başka bir boyut daha vardır. Bu, yukarıda tartışılan yazılımın farklı yönleri (ya da biçimleri) arasındaki bağlantılar ağıdır; gereksinim ifadesinden özelliklere, tasarıma, koda ve test sonuçlarına uzanan temsil zinciri.

Teknik sorun, genellikle tasarım-güncelleme problemi olarak adlandırılır. Genellikle olan şudur: Sistem temsillerinden oluşan dikkatli bir zincir kurulmuş olsa bile, sistem var olduktan sonra programlarda değişiklikler yapılır; ancak bu değişiklikler tasarım ve özelliklere geri yansıtılmaz. Sonuç şudur: Sistemin daha soyut temsilleri hızla işe yaramaz hâle gelir ve gelecekteki değişiklikler yalnızca program listeleri (ya da eşdeğer derecede düşük seviyeli bir temsil) kullanılarak yapılmak zorunda kalır.

Bina inşaatında bu, planlar veya standartlar olmadan inşa etmeye ve ilk yapımdan sonra boruların ve kabloların nereye yerleştirildiğine dair hiçbir kayıt tutmamaya benzer; öyle ki, binada gelecekte yapılacak değişiklikler yalnızca kabloların nerede olduğunu bulmak için duvarların yıkılmasını gerektirir.

Yazılımın değiştirilmesinin zor olduğu gerçeğinin sonuçları nelerdir? Genel olarak iki tanedir. Birincisi, sistemi sonsuza kadar yaşayacakmış gibi kurmak; yol boyunca pek çok değişikliğe dayanmasını beklemek. İkincisi, herhangi bir sistem üzerindeki kontrol ve değişiklikler çok dikkatli bir şekilde yapılmalıdır. Şimdi ilk sonuca biraz daha yakından bakalım.

Eski Kod Asla Ölmez

Bu, pek çok insanın ve kuruluşun yıllar önce öğrendiği bir gerçektir. Ancak alandaki insanların ortalama deneyim süresi düşüyor gibi göründüğünden (bilgisayar kullanımının ve dolayısıyla insanların yazılım geliştirmeye katılımının hızla artması nedeniyle), bu ders insanlar tarafından sürekli olarak zor yoldan yeniden öğrenilmektedir.

Yazılım pek çok nedenden ötürü — iyi ya da kötü — sonsuza dek yaşar. En açık ve yaygın neden, bir kez geliştirilip üretken kullanımda yer aldığında, onu değiştirmek ya da yerine yenisini koymak için aşılması gereken bir atalete sahip olmasıdır. Kullanıcılar onu sever. Yönetici sever. Müşteriler sever. Yavaş olması, hatalara yatkın olması, yeni işlevleri karşılamak için genişletilmesi gerekmesi vb. önemli değildir. Yazılım yaşamlarının bir parçası hâline gelmiştir ve istedikleri tek şey biraz düzeltilmesidir — kesinlikle yerine konması ya da büyük ölçüde değiştirilmesi değil.

Yazılım ile etrafındaki insanlar (kullanıcılar, müşteriler, yöneticiler, operatörler vb.) arasındaki ilişki, tarihsel nedenlerle bir arada bulunan insanlar arasındaki ilişkiye (örneğin bir evlilikte, iş durumunda, komşulukta) hiç de benzemeyen değildir; bu ilişkinin mevcut durumla pek ilgisi olmayabilir. Durumu değiştirmek ve yazılımla olan ilişkiyi koparmak olağanüstü miktarda çaba gerektirir. Sonuç: yazılım yaşamaya devam eder.

Yazılımın ölmemesinin, üretim sürecindeki yakın rolünden kaynaklananların ötesinde, sıklıkla ekonomik nedenleri vardır. Herhangi bir büyüklükteki yazılım, ilk etapta geliştirilmesi oldukça maliyetlidir (ve daha da kötüsü, genellikle bir sermaye maliyeti olarak değerlendirilemez). Eğer uzun süre kullanılmışsa, büyük olasılıkla yıllar içinde onu onarmak, uyarlamak ve yeni işlevlerle zenginleştirmek için hatırı sayılır miktarda para harcanmıştır; bu şekilde başlangıçtaki geliştirme maliyetinin üç ya da dört katının harcanmış olması alışılmadık bir durum değildir. Bu, ondan kurtulma konusunda (kullanıcılar artık değiştirilmesi gerektiği konusunda hemfikir olsa bile) beklenen ataleti üreten büyük bir yatırıma dönüşür.

Son olarak, "hızlı" bir uygulama için, yani sınırlı bir süre dayanacağı ve sonrasında atılacağı varsayılan bir yazılım parçası geliştirmek ve yalnızca uygulamanın o kadar üretken olduğu ortaya çıktığı için, hızlı (ve özensiz) yazılımla birlikte kullanıma devam etme kararının alınması da hiç de nadir değildir.

Çıkarılacak ders şudur: yazılımın asla ölmeyeceğini varsaymalısınız. Onu, kendi emekliliğinizin çok ötesinde yaşamaya devam edecekmiş gibi kurun; yeni donanımlarda çalışacak şekilde uyarlanacak, yeni işlevlerle zenginleştirilecek, can sıkıcı özel durumları ele almak için onarılacak ve genel olarak onu geliştirenlerden daha uzun yaşayacaktır. Elbette karşı örnekler vardır — gerçekten tek seferlik durumlar, yakında kullanım dışı kalacak ekipmanlar için uygulamalar, sonunda modası geçen işlevler — ancak geleceğe fazla hazırlanma tarafında hata yapmak, yetersiz hazırlanmaktan daha iyidir.

Yazılım, istenmeyen akrabalar gibi, ondan kurtulması zordur.

Bir Ürün Olarak Yazılım

Bilgi işlemin tarihi, programların son derece matematiksel bir doğaya sahip olduğu, yalnızca birkaç kişi tarafından anlaşılan ezoterik problemleri çözmek için dâhi matematikçiler tarafından geliştirildiği görüşünü beslemiştir. Gerçekten de, birçok erken dönem programın ve onları geliştiren insanların doğası buydu. Bilgisayarlar daha geniş bir görev yelpazesine uygulanmaya başlandıkça, insanların aslında bilgisayarların yalnızca sayı hesaplayan makineler değil, çok genel sembol işlemcileri olduğunu fark etmeleriyle bu görüş değişmeye başladı. Bilgisayarların yaptığı sayısal olmayan (ya da en azından yalnızca çok basit aritmetik içeren) işlerin büyük miktarı ve milyonlarca insan tarafından çok sıradan görevler için kullanılan kişisel bilgisayarın ortaya çıkışı nedeniyle, bu görüş artık baskın hâle gelmiştir.

Birincinin açık bir sonucu olan başka bir görüş de, yazılımın; tanımlanan, paketlenen, stok kontrolü ve türev modelleri hakkında kaygılanılan, pazarlanan, satılan, bakımı yapılan ve eskidiğinde dağıtımdan kaldırılan bir ürün olmadığı yönündeydi. Bu görüş de son 20 yılda köklü biçimde değişti; ancak bu değişim, bilgisayarın temel doğasına ilişkin görüşteki değişim kadar yaygın ya da dikkatle benimsenmiş değildir.

1960’ların sonlarında yazılımın donanım fiyatından ilk kez "ayrıştırılması" ile başlayan süreçten itibaren, yazılım giderek bir ürün olarak görülmeye başlandı; son beş yılda kişisel bilgisayar alanındaki patlayıcı büyüme, yazılımın gerçekten de bir ürün olarak ele alınabileceğini çoğu (herkes değilse de) insan için son derece açık hâle getirdi.

İlginçtir ki, pek çok "yazılım milyonerinin" eski kuşak profesyonel programcılar olmadığı, aksine çeşitli bağlamlarda belirli bir yazılım ürününe olan ihtiyacı hızla kavrayan, onu geliştiren, paketleyen ve pazara ilk ulaştıran insanlar olduğu görülmektedir.

Gerçekten de, en başarılı yazılım ürünlerinin birçoğu teknik açıdan çok sofistike değildir (burada da bir ders vardır).

Bir ürün fikrini ortaya koymak, onu inşa etmekle aynı şey değildir. Onu pazarlamak ve satmak da inşa etmekle aynı değildir. Gerçek bir ürün geliştirirken, servis edilebilirlik, güvenilirlik, müşteri zevkleri, üretim maliyeti vb. konulara dikkatle odaklanmak gerekir. Bir ürün yapmanın ne anlama geldiğine ilişkin bu yönler, geliştirme topluluğu tarafından ancak yeni yeni anlaşılmakta ve dikkate alınmaktadır. Yazılım ürünleri alanındaki en büyük başarıların birçoğunun profesyonel olmayanlar tarafından geliştirilmiş olmasının nedeni bence budur.

Bazen bazı teknik insanların ürün konusundaki bilgisizliği aslında bir nimettir. Yazılımın kendisini geliştirirken, teknik özelliklere odaklanmak ve ürün parametrelerinin kısıtları içinde en iyi teknik çözümü bulmak önemlidir. Herkes ürün parametrelerine odaklanırsa, tatmin edici bir teknik çözüme ulaşmak daha zor olabilir.

Belki de en önemli şey, yazılımın ürün ve teknik yönleri arasında dengeyi korumaktır. Tüm yazılımlar nihayetinde başkası için bir üründür (belki yalnızca geliştiricinin onu farklı bir bağlamda kullanması için); bu nedenle ürün yönlerini uygun biçimde ele almak önemlidir. Öte yandan, tümüyle paketleme ve içeriksizlik, tümüyle içerik ve paketsizlikten bile daha kötüdür (ki bu genellikle daha kolay giderilebilir).

Yazılımı bir ürün olarak görmek, geliştirme süreci için hızla birçok sonucu beraberinde getirir: anonim bir kullanıcı kümesinden gereksinimleri nasıl belirleyeceğimiz, tasarım ve gerçekleştirme sürecini nasıl hızlandırabileceğimiz, yayımlandıktan sonra değişiklikleri nasıl ele alacağımız vb. Bu konuların bazıları, geliştirme sisteminin bireysel parçaları bağlamında daha sonra ele alınacaktır.

Yazılıma hem bir ürün hem de teknik bir nesne olarak yaklaşın.

Bu bağlamda, yazılımın temel ürün özelliklerinden birini, yani özünde paketlenmiş bilgi olduğunu kabul etmek önemlidir.

Yazılım Bilginin Somutlaşmış Hâlidir

Yazılıma ilişkin özellikle çekici bulduğum bir bakış açısı (belki görkemli çağrışımları nedeniyle, ama ben tüm kapsayıcılığı nedeniyle olduğunu düşünmeyi tercih ediyorum) şudur: yazılım bilginin somutlaşmış hâlidir. Her program, bir sürece ve onu yürütmek için ilgili olan verilere dair kesinlikle büyük miktarda bilgi içerir. Programlar ayrıca, farklı süreçler (programlar) ile onlara eşlik eden veriler arasındaki ilişkileri gösteren yapısal bilgiyi, veri sınıfları arasındaki ilişkiler hakkındaki bilgiyi ve bunun gibi başka bilgileri de içerir.

Eğer yazılım olarak adlandırdığımız temsil zincirinin son ürünü olan programlar, dış dünya hakkında bilgi içeriyorsa, o hâlde daha önceki sürümler — tasarımlar, spesifikasyonlar ve gereksinimler — de kesinlikle bilgi içerir. Gerçekten de yazılımın gerçeklerinden biri, sistemin bu biçimlerinin çoğu zaman değerli bilgiler barındırması ve yürütülebilir sürümlere gelmeden önce bu bilgilerin kaybolmasıdır.

Bu bakış açısının tumturaklılığı hakkında ne düşünürseniz düşünün, üzerinde düşünmeye değer olduğu kesindir. Eğer yazılım bilgiyse (çok açık görünen bir şeyi size kanıtlamak için fazla sözcük harcamıyorum), o zaman yazılım geliştirme ortamında var olan bilginin düzgün biçimde yakalanması ve yönetilmesi için büyük özen gösterilmesi gerektiği yönündeki sav kesinlikle yeni bir önem kazanır. Benzer şekilde, sıkça dile getirilen, programların gerçek kodlanmasından önce gelen etkinliklere daha fazla dikkat edilmesi gerektiği yönündeki çağrıya da ağırlık kazandırır. Bu etkinlikler, program planları kadar değerli, hatta en az onlar kadar önemli bir şey üretmektedir — bilgi. Bu durum, yazılımın yeniden kullanılabilirliğinin temel itici güçlerinden biridir.

Programlama — dar anlamıyla, bir makineye tam olarak ne yapacağını söyleyen talimat kümelerini ortaya koyma — bir araştırma raporu yazmaya benzetilebilir. Yazma başlamadan önce edinilmiş olan bilginin bir temsilini üretir.

Bu bağlamda, yazılım geliştirmenin erken aşamalarında yaptığımız şeyin bilgiyi ortaya çıkarmak ve düzenlemek olduğu açık görünmektedir. Önce, ve büyük resim açısından en önemlisi, uygulama hakkında bilgi üretiriz; ardından tasarım sırasında, uygulamayla bilgisayar aracılığıyla nasıl başa çıkılacağına dair bilgi üretmeye geçeriz.

Bu iki keşif süreci (ve kullanılan yöntemler) arasındaki etkileşim karmaşıktır ve iyi anlaşılmış değildir. Bu süreçler arasındaki ilişkinin kendisi ise daha da belirsizdir.