Çarşamba, Temmuz 18, 2007

Özellik Yönelimli mi? Vaka Yönelimli mi?

Bu yazıda iki temel yazılım geliştirme tekniğini inceleyeceğiz.

Program yazarken genelde yaptığımız şey şudur. Programın yapması gereken bir iş belirleriz. Sonra programa o işi yaptırıncaya kadar kodlar dururuz. Kodlama yaparken aklımıza birşeyler gelir. Elimiz değmişken müşteriyi memnun edeceğini düşündüğümüz bu özellikleri ekleriz. Hadi buna bir isim verelim ve bu işi belirleme ve belirlediğimiz işi programa yaptırma olayına Üretim Süreci diyelim.

Üretim sürecinin bir iş belirleme ve o işi yapma adımlarının arasında aslında bir de analiz adımı vardır. Yani bir iş belirlenir. Bu işi programın nasıl yapacağı analiz edilir ve yaptığımız analize göre kodlama yapılır. Gerçekte bir de tasarım aşaması var ama şimdilik onu kodlama aşamasına dahil edelim. Programın yapacağı işe de gereksinim diyelim.

Özetlersek önce bir gereksinim seçiyoruz, bu gereksinimi programın nasıl karşılayacağına karar veriyoruz ve programı yazıyoruz.

Yapacağımız iş ne olursa olsun, işin nasıl yapılacağının analizinde iki temel yöntem vardır. Tümdengelim ve Tümevarım. Eğer konunun bütünü hakkında yeterli bilgimiz varsa Tümdengelim tekniğini uygularız. Yani konuyu bir bütün olarak ele alırız ve bütünü oluşturan parçaları araştırırız. Eğer konu hakkında yeterince bilgi sahibi değilsek o zaman Tümevarım tekniğini uygularız. Yani bütüne ait olduğunu tahmin ettiğimiz küçük parçaları ele alırız ve onları biraraya getirerek bir bütün oluşturmaya çalışırız. Tümevarım tekniğinin çok önemli bir riski vardır. Küçük parçalardan bütüne ulaşma çabası herzaman başarılı sonuç vermez. Bütüne hakim olmadığımız için elimizdeki parçalar bizi gerçekte olandan çok farklı bir noktaya götürebilir.

Örneğin inşaat işi yaptığımızı düşünelim. Eğer nasıl bir bina yapacağımız belli ise o zaman inşaatın sonucunu düşünerek bir proje hazırlarız. İşleri küçük parçalara böleriz. Bu aşamada inşaat sırasında karşılacağımız sorunların büyük bölümünü kağıt üzerinde çözeriz. Sonra hangi iş bitince hangisinin başlayacağını belirleriz ve planımıza uygun şekilde işi organize edip uygulamaya geçeriz. Ulaşacağımız sonuç başta planladığımızla aynı olacaktır. Eğer bir bina yapacağımızı biliyor ama nasıl bir bina yapacağımızı bilmiyorsak o zaman elimize malayı, tuğlayı alıp duvarın bir tarafından örmeye başlarız ve ilerleme durumumuza göre sonraki işin ne olacağına karar vermeye çalışırız. Bu yöntemle başta amaçladığımız sonuca ulaşma ihtimalimiz çok düşüktür. Yapacağımız küçük bir klübe ise konuya hakimiyetimizi kaybetmeden işi bitirme ihtimalimiz olabilir ama bir gökdelen yapmaya kalkarsak bir yerden sonra ip kopar.

Tabiiki inşaat yapmıyoruz program yazıyoruz, burada bazı farklar var. Farklar çok olsa da program üretirken de Tümevarım ve Tümdengelim yöntemleri kullanılır. Biz bu iki program yazma yöntemine Özellik Yönelimli (Feature Driven) ve Vaka Yönelimli (Case Driven) programlama diyoruz. (Türkçelerini ben şimdi uydurdum. Türkçe başka şekilde ifade ediliyorsa onları da araştırıp yazıma eklerim. Şimdilik böyle devam edelim.)

Eğer çevremizde "Programa şöyle bir özellik ekledik." veya "Programda şu özellik olmadığı için müşteri programı almadı" şeklinde konuşmalar yapılıyorsa Özellik Yönelimli Programlama yapıyoruz demektir.

Eğer "Kullanım vakası bu kullanım senaryosuna uygun değil" veya "Bu kullanım vakası müşteri gereksinimlerini tam karşılamıyor" gibi konuşmalar yapılıyorsa Vaka yönelimli Programlama yapıyoruz demektir.

Asıl amacım bu yöntemlerin tanıtımını yapmak değil. Amacım yazılım üretiminde sık yapılan bir hataya dikkat çekebilmek ve projelerin aslında müşteri gereksinimlerine paralel gitmesinin ne kadar önemli olduğunu anlatabilmek. İyisi mi gerçek hayat örnekleri üzerinden düşünerek devam edelim.

Öncelikle basit bir örnek düşünelim. Bir program yazarak yazılım sektöründe devrim yapmayı planlamaktayız. Herkes bu programı satın almalı. Programımız bir satış programı olsun. Stok kartları olacak. Alış faturası ile mal alınacak, Satış Faturası ile satılacak. Program bu evraklarla yapılan hareketleri baz alarak Stok Envanterini ve Stok Karlılık Raporunu verecek. Bir de müşterilerin borcunu alacağını tutacak. Programı ne tür bir müşterinin kullanacağını ve müşterin gereksinimlerini bilmediğimiz için konuya şöyle gireriz.

Temel parça stok kartı. Stok kartı olmadan fatura kesemeyiz. Önce stok kartını düşünelim. Stok kartında ne olur? Stok kodu, Malın Cinsi, Barkod, Birim, Satış Fiyatı ve raporlar için birkaç tane özel kod olur. Biz bunları düşünürken çok bilgili arkadaşımız "Böyle yaparsan bu programı bilgisayar parçası satanlar kullanamaz çünkü onlar malı dövizle alıp satarlar" der. Tamam sorun yok Döviz satış fiyatı özelliğini de koyalım. Döviz koyacaksak kur bilgisinin girileceği bir alan daha gerekir. Sonra başka biri "Buna bir de peşin fiyatı, veresiye fiyatı lazım der" peki 2. Satış Fiyatını da koyalım hatta elimiz değmişken bir de 3. satış fiyatı koyalım zengin göstersin. Bunların döviz karşılıklarını da girecek alanlar koyalım. Tabii bitmez. Başka biri "aaa ama ürünün adet barkodu farklı paket barkodu farklı" der. Tamam birim bazında barkod tanımlama özelliğini de koyduk. Başka biri "ya geçen bi müşteriye gittim adam stok kartında 3. iskonto tanımlama özelliği olmadığı için 5 yıldır kullandığı program bırakmış" der. 3. İskonto mu? Hmm 3 iskonto kullanan yerleri kaçırmamak lazım. Stok kartına 3 tane de iskonto tanımlama alanı açalım. Peki 3 tane de fiyat koyduk? Peşin alana da veresiye alana da aynı iskontolar uygulanacak mı? Neyse konu biraz karıştı. Şimdilik karta direk koyalım sonra biri istek yaparsa çaresine bakarız.

Evet stok kartı tamam. Kodladık güzel oldu. Şimdi satış faturasına geçelim. Faturada ne olur? Bir başlık bölümü, bir hareket bölümü bir de genel toplam bölümü olur. Başlığa ne koyacağız? Belge Tarihi, Belge Numarası, stok kartında döviz de olduğuna göre başlığa bir de döviz seçeneği koyalım. Müşteri kartının seçileceği bir alan açalım. Müşteri kartı mı? Hmm o zaman önce müşteri kartını yapalım. Bu böyle sürer gider...

Bu arada başka bir yazılım evinde olaylar daha farklı gelişmektedir. Şirket yönetimi giyim malları satan yerlerde kullanılacak bir satış programı yazmayı planlamaktadır. Kullanacak kitle tanımlıdır. Programın çözeceği problem de bellidir. Giyim satışı konusunda deneyimi olan birisiyle yapılan görüşme neticesinde şöyle bir döküman hazırlanır.


Giyim Satış Programı

Vaka No:1 Satış Sorumlusu Satış Yapar

  1. Müşteri satın alacağı ürünleri kasaya getirir
  2. Satış Sorumlusu yeni satış komutu verir
  3. Sistem Satış belgesini hazırlar, otomatik belge no ve tarih verir, boş bir hareket ekler ve belgeyi gösterir.
  4. Satış Sorumlusu ürün barkodunu okutur.
  5. Sistem barkoddan stok kartını bulur, karttan satış fiyatını okur, harekete stok kodunu, malın cinsini satış fiyatını yazar, belge toplamını günceller ve yeni satıra geçer.
  6. Satış sorumlusu tüm mallar belgeye ekleninceye kadar 4. adımdan devam eder.
  7. Satış Sorumlusu ödeme şeklini (Nakit, Kredi Kartı) seçer.
  8. Sistem ödeme şeklini ekranda gösterir.
  9. Satış sorumlusu belge yazdırma komutunu verir.
  10. Sistem belgeyi kaydeder ve yazıcıya belgeyi gönderir.
  11. Bitti.

Bu döküman işletmede yapılan bir faaliyetin bilgisayara kaydedilmesi sırasında girilen bilgilerin ve program ile kullanıcının etkileşiminin gösterildiği bir kullanım vakasıdır (Use Case) Bu vakayı programlayacak programcı bu işlemin yapılabilmesi için stok kartına hangi bilgilerin konulması gerektiğini araştırır. Bu vakayı tamamlayabilmek için Stok kartında Barkod, Stok Kodu, Malın Cinsi, Satış fiyatı alanlarının olması yeterlidir. Ya birim? Döviz fiyatı? Programın hedefi giyim satışı yapanlardır. Giyim satanlar koliyle gömlek satmazlar. Döviz kullanan da bazı yabancı kökenli mağazalar haricinde pek yoktur. Aslında giyim satan bir mağazanın stok kartında birim gibi bir bilgi olması bile hem veri hem de görünüm anlamında fazlalıktır. Ya iskonto? Mağazalar indirim yapmazlar mı? 2 numaralı "Kampanya Kullanım Vakası" üzerinde yapılan inceleme neticesinde giyim mağazalarının iskontoyu belli bir grup ürüne yaptığı ortaya çıktığı için rakibimiz iskontoyu stok kartına koymamış onun yerine başka bir yerden yazlık gömlek grubu veya kışlık pantolon grubu gibi belli gruplara topluca iskonto yapılmasını sağlamış. 2. ve 3. iskontoyu koymaya da gerek bile duymamış. Peki giyim satan kişi benim programımı kullansa kampanya döneminde ne yapacaktı? Önce tek tek her stok kartına iskonto vermeye çalışacaktı. Bu zor gelmeye başlayınca benden topluca stok kartlarına iskonto yapılmasını sağlayacağım bir özellik isteyecekti.

Biz özellikleri birarada çalıştırmaya ve müşterilerimizin isteklerini yapmaya uğraşırken rakibimiz başından sonuna bir işin yapılabildiği çalışan birşeyler üretmiş ve buna ihtiyaç duyacağını düşündüğü müşterilere gitmeye başlamıştır.

Kullanım vakaları kullanım senaryoları ile geliştirilir. Kullanım senaryosu bir gerçek hayat örneğidir. Mesela şöyle bir senaryo düşünelim. Müşteri ürünleri kasaya getirmiş ve satış sorumlusu ürünleri okutmaya başlamıştır. Tam ürünleri okuturken müşteri "bir dakika" der o anda gözüne çarpan bir eteğe bakmak üzere kasanın önünden ayrılır. Satış sorumlusu ne yapar? Kullanım vakamız bu senaryoyu karşılayabilir mi? O an yapılan satışın duraklatılması ve sıradaki müşteriye geçilmesi durumunu karşılayacak şekilde kullanım vakası güncellenir. Programcı vakayı tamamlayacak şekilde programı günceller, vakanın her adımının tamamını test eder. (veya test kodunu günceller) Programın bir yerinde değişiklik yapılması durumunda çalışma şeklinin ne olması gerektiğini kullanım vakası (Use Case) belgelemektedir. Bir değişiklik yaparken başka bir işlevin bozulması gibi bir risk çok düşüktür.

Sonuçta işe yarar bir fatura yazma ihtimali vaka yönelimli hareket edildiği zaman hep daha yüksektir çünkü tümdengelim yöntemi kullanılmaktadır ve parçaların taşıyacağı özellikler bütüne bakılarak belirlenmektedir. Programcılıkta en kötü olay programın tamamlanmamış vakalar içermesidir. Örneğin programda yapılması gereken iki iş olduğunu ve ne yapılacağına programcının karar verebileceğini düşünelim. Birisi "seri numaralı satış yapma özelliği" birisi de "faturayı yazıcıdan çıkarma" özelliği olsun. Özellik yönelimli düşünen programcı büyük ihtimalle seri numaralı satış özelliğini eklemeyi düşünecektir çünkü bu özellik programın hitap ettiği kitleyi genişletecek ve programın satılma ihtimalini yükseltecekir. Kimse programı yazıcıdan çıktı verip vermediğine bakarak almaz ama seri numaralı satış yapan bir müşteri bu özelliği görmek ister. Programcı bıçak kemiğe dayandığında fatura çıktısının nasıl olsa yapılabileceğini düşünür. Halbuki vaka yönelimli düşünen birisi böyle bir tercih yapma durumunda bile kalmaz. Program fatura yazdırmadan daha ilk vaka bile tamamlanmamaktadır. Bir vaka tamamlanmadan diğerine geçilmeyeceği için program fatura kaydeden ama çıktısını veremeyen bir duruma asla geçmez. Özellik yönelimli programlamada hemen her zaman programda buna benzer bir eksiklik olur.

2 önemli tespit yaparak konuyu sona erdirelim.

Üretim tekniği yazılımevinin bütün organizasyonuna sirayet eder. Bir programın demosu yapılırken programın hangi teknikle hazırlandığını hemen anlayabiliriz. Eğer demoyu yapan kişi "Faturada x özellik var" "stok kartında y özellik var" şeklinde anlatım yapıyorsa o yazılımevi özellik yönelimli çalışmaktadır. Eğer demoyu yapan kişi önce müşterinin kullanım senaryolarını sorguluyor sonra programın bu kullanım senaryolarında nasıl kullanıldığını gösteriyorsa o yazılımevi vaka yönelimli çalışmaktadır.

Gördüğü süper özelliklerden çok etkilenerek özellik yönelimli üretilmiş bir programı satınalan birisi programı kullanmaya başladığı andan itibaren hayal kırıklığına uğrar. Programda süper özellikler vardır ama bu özellikler sistem ile kullanıcı etkileşimi düşünülmeden eklendiği için özelliklere ihtiyaç olan yerde ulaşmak her zaman mümkün olmaz. Program adamın sırtını bile kaşıyacak özelliklere sahiptir ama kullanıcı ihtiyaç duyduğu anda bu özelliklerden tam faydalanamaz. Örneğin faturaya herhangi bir satırdaki stoğun alış fiyatına bakma özelliği eklenmiştir. Halbuki kullanıcı sadece fiyata bakmak için faturaya satır eklemek istememektedir çünkü faturaya hangi stoğu ekleyeceğine fiyatına bakarak karar vermek istemektedir.

Sonuçta özellik yönelimli programlamaya iyice yüklenmiş olduk. Tabii bu kadar kötü görünmesinin nedeni örneği XP gibi herhangi bir yöntem kullanılmadığını düşünerek vermiş olmam. Böyle bir temel olduğunda özellik yönelimli programlama yaparak iyi sonuç alabilmek mümkün.

Hiç yorum yok: