Arda Çetinkaya Thoughts on software, with the occasional personal rambling…

Agile yazılım geliştirme metodlarından Scrum’da, geliştirme sürecinde, çıkacak ürünün özelliklerini ortaya çıkarabilmek ve bunları iyi analiz edebilmek çok önemli. X adında bir ürün geliştireceğimizi düşünelim. Belli bir amaç için geliştirdiğimize göre, bu amaç(lar) doğrultusunda ürünümüzün belli özellikleri olacaktır. Bu özelliklerin uygulanma açısından da çeşitli fonksiyonlar olacaktır. Tabi bütün bunlar son kullanıcı ya da ürün sahibinin ihtiyaçları ve üründe gerçekleştirmek istediği işlerden(scope) oluşacaktır.

Scrum’da bunların listesine “Product Backlog” deniyor. Scrum’ın uygulanabilmesi için olmazsa olmaz bir kavram bu “Product Backlog”. “Product Backlog” listesi oluşturulurken, analiz sonuçlarından ve daha önceki projelerdeki tecrübelerden yararlanılır. Bu liste sadece yapılacak ürünün özelliklerini içermek zorunda değildir. Ürünün özellikleri ile ilgili, önceki tecrübelerden ortaya çıkmış ve ürünü geliştirirken etki edebilecek kavramlarda bu listeye alınmalıdır. Teknik olarak geliştirme sürecinde direk olarak bir şey ifade etmeyen ama dolaylı olarak ürünün genelinde etki edebilecek kavramlar da bu liste dahilinde ele alınabilir.

Bu liste oluşturulurken, herkes katkıda bulunabilir. Geliştiriciden, ürün sahibine, proje yöneticisinden, test ekibine kadar geniş bir kesim bu listenin oluşmasını sağlar. Ne kadar çok katkı olursa o kadar sağlıklı bir “Product Backlog” çıkacaktır.Tabi herkesin katkı yapıyor olması, her katkının da bu listeye dahil olacağı anlamına gelmiyor. Tabi ki listeyi oluştururken de “scope”un dışına çıkmamak gerekiyor.

Bu listenin en önemli ve Scrum tarafından anlam taşıyan bir diğer özelliği listedeki maddelerin bir öncelik(priority) sırasına sahip olması. Bu öncelik sırası, sadece ürün sahibi(product owner) tarafından belirlenmelidir. Bunun nedeni az önce de kullandığım “scope” kavramının dışına çıkılmasını engellemektir.

Şimdilik bu kadar, bu konuda her türlü fikrinizi,düşüncenizi veya sorunuzu bekliyorum…

Bir önceki yazımda WPF’de kontrol içerisindeki kontrollerde oluşan “event” sorunundan bahsetmiştim. Aslında sorun değil, WPF’deki “event” yaklaşımının biraz farklılaştığını belirtmeye çalışmıştım. Bu yazıda biraz daha derinlere girip, WPF’deki “Routed Events”‘den bahsetmeye çalışacağım.

WPF, kullanıcı deneyiminin uygulamalarda daha rahat bir şekilde uygulanmasını amaçlıyordu hatırlarsanız. WPF’in ortaya ilk çıktığından beri Microsoft’un altını çizdiği nokta bu yönde. Bu bağlamda, standart bilgisayar uygulamalarında ki standart arayüzler yerine kullanıcının çok daha kolay kullanabileceği bir arayüz sunmak ve bu arayüz ile sunulan bilgileri de daha anlamlı bir görsellikte sunarak kullanıcı deneyimini uygulamalara katmak WPF’in ilerlediği yollardan bir tanesi diyebiliriz. Bu yaklaşımdan dolayı, WPF ile beraber alıştığımız kullanıcı kontrollerinden farklı bir yapı karşımıza çıkıyor. Tıkladığımız düğmeler WPF ile beraber daha farklı amaçlar için kullanılabilir hale geliyor. Ya da bir çok elemandan, seçim yapabileceğimiz kullanıcı kontrolleri içerik olarak daha anlamlı bilgiler içermeye başlıyor.

Mesela bir düğme(button)nin içine resim koyarak, düğmenin görselliğine farklı anlamlar yükleyebiliyoruz.Bu çok basit bir örnek oldu gerçi ama demek istediğim, WPF’de kullanıcı kontrollerini, farklılaştırarak zenginleştirebiliyoruz. Kontrolleri iç içe kullanabiliyoruz. Bir “button”(düğme) içine “image”(resim) kontrollü koymak gibi. Katmanlı bir kullanıcı kontrolü yapısı var demek biraz daha netleştirebilir belki.

“Routed Events” kavramı da bu yapıdan dolayı ortaya çıkıyor. Yukarıda bahsettiğim kontroller üzerinden örneklendirmek daha anlaşılır olacak sanırım. Aşağıdaki uyduruk resimde(:)) bir “button” içinde “image” var.

Şimdi “button”a tıklandığı zaman “click” olayı oluşur bildiğiniz üzere. Ve tıklandığı zaman ne olmasını istiyorsanız bu olaya(event) denk gelen metodda ilgili kodu yazarsınız. “button” tıklandığı zaman ne oluyorsa, aynı işlem üzerinde “image” kontrolü olan “button”a tıklandığında da olmalı. Tıklanan alan “image” kontrolüne denk geliyorsa tıklama işleminin “button” tarafından da anlaşılıyor olması lazım. Bundan dolayı “image” üzerinde bazı işlemlerin, “image”ı içeren kontroller tarafından da algılanabiliyor olması lazım. WPF bu işlemi “routed events” kavramı ile gerçekleştiriyor.Özetle WPF’de bir “event” başka elemanlara yönlendirilebiliyor.

Bir önceki yazıda gerçekleşen olayın sebebi bu yani. WPF’de bir uygulama geliştirirken, “routed events” kavramını kendi geliştireceğiniz kontrollerde kullanmanız kaçınılmaz olacaktır. İlerleyen yazılarda bununla ilgili çok basit bir örnek göstermeye çalışıyor olacağım…Şimdilik bu kadar.

Not: “button” ve “image” anlaşılır bir örnek olması açısından kullandığım kavramlar. WPF’deki mevcut tüm yapılar için “routed events” kavramı geçerlidir.

, ,

Geçen gün bir arkadaşımın WPF(Windows Presentation Foundation)’den çektiği dertleri Twitter’dan gördüm ve benzer bir sorunu yaşadığım için şaşkınlığını çok iyi anladım. WPF kavram olarak çok güzel şeyler vaad ediyor olsa da, açıkcası tam olarak oturmuş bir yapı olduğuna inanmıyorum. İlk çıktığı zamandan beri kendimce küçük uğraşlar ile WPF’i elimden geldiğince takip etmeye öğrenmeye çalıştım,çalışıyorum da. Diğer .NET Framework yapıları ile kıyaslandığında farklılıkları ve değişiklikler ciddi anlamda uğraştırıyor.Neyse çok dağıtmadan konuyu, özüne dönelim.

WPF’de “control” yapısı, ASP.NET ve Windows yapısına göre biraz daha farklı. Bu farklara değinmek şimdi uzayacağından sadece farklı olduğunun altını çizmek yeterli olacaktır şu aşamada.

Sorunumuz ne peki? TabControl içinde kullandığımız Listbox,Combobox gibi yapılarda “SelectionChanged” event’i(olayı) çalıştığı zaman tabcontrol’ün de “SelectionChanged” event’i çalışmakta.Bunun nedenlerini inceleyerek sorunu çözmek, WPF’i anlamak adına daha faydalı olacağından olayın en temeline inerek çözümü sunmaya çalışacağım.

WPF’de “Selector” diye bir sınıf var. Listbox,Combobox gibi seçme işleminin yapılabileceği kullanıcı kontrolleri bu sınıftan türemekte.  “Select” operasyonunun yapılacağı kontrollerin “Selector”dan türemesi kavram olarak bakıldığında çok normal. WPF’de TabControl diye bildiğimiz sekmeli bir yapı sunan kontrolde WPF’de “Selector”dan türemekte.Yani ListBox,Combobox ve TabControl aynı kategoride diyebiliriz daha basitçe.Bu kontrollerin “SelectionChanged” event’i Selector sınıfından gelmekte ve dinlenmekte. TabControl’ün veya Combobox’ın ne yazık ki kendilerine özgü düzenlenmiş bir SelectionChanged event’i yok.Bundan dolayı “Selector.SelectionChanged” event’i tetiklendiği zaman Selector sınıfından türeyen sınıflarda bu event’i kontrol etmeye çalıştıklarında başarılı olacaklardır.Yani daha açık bir şekilde; TabControl’ün SelectionChanged event’inde çalışan bir metodu olduğunu varsayalım:

81 protected void TabControl1_SelectionChanged(object sender, SelectionChangedEventArgs e)

82 {

83 //tab seçildi

84 }

Aynı şekilde Tabcontrol’ün içindeki bir ComboBox’ın da aynı event’de çalışacak bir metodu olduğunu varsayalım:

86 protected void Combobox1_SelectionChanged(object sender, SelectionChangedEventArgs e)

87 {

88 //combox’da seçildi

89 }

Uygulama çalıştığı zaman ComboBox’dan bir seçim yaptığınızda, ComboBox’ı içeren kontrolün(TabControl oluyor bu durumda) de SelectionChanged olduğu zaman çalışacak metod da çalışacaktır…Çok ilginç değil mi? Bunun nedeni yukarıdaki kısa açıklama. Ama asıl nedeni WPF’de ki event mekanizması.WPF ile beraber Routed Events diye bir kavram hayatımıza giriyor.Bir sonraki yazımda bunun ne olduğunu anlatmaya çalışacağım, çünkü WPF ile uğraşanlar için oldukça önemli bir şey olduğuna inanıyorum.Neyse sorunumuza dönelim…Şimdi en son combobox’ı seçmiştik ve tab kontrolününde metodu çalışmıştı. Bunu istemiyoruz tabi ki…Peki ne yapacağız…

Event argümanlarının(e parametresi oluyor metoddaki) “Handled” diye bir özelliği var. Bu özelliği “true” olarak değiştirdiğiniz zaman oluşan olayı(event) yakalamış olduğumuzu belirtiyoruz.

86 protected void Combobox1_SelectionChanged(object sender, SelectionChangedEventArgs e)

87 {

88 //combox’da seçildi

89 e.Handled = true;

90 }

Bu sayede TabControl’ün event’i çalışmamış oluyor…WPF ile geliştirme yaparken, bu tarz sorunları aslında sorun olarak değilde, değişiklik olarak algılamak gerekiyor sanırım.Neyse şimdilik bu kadar…Her türlü soru,sorun,düşünce fikir paylaşımına açığım,bekliyorum…(:

, ,

Projelerde yapılacak işlerin ne kadar süre içerisinde yapılacağını tahmin etme süreci oldukça sıkıntılı geçer. Her ne kadar yapılacak işlerin analizini iyi yapmış olmak bu sürece olumlu katkı sağlasa da, öngörülemeyen sorunların ya da ihtiyaçların etkilerini bu süreç kapsamında kestirmek zor olduğundan yapılan tahminler çok geçerli olmaz. Sürecin adı “Estimation”(tahmin) olarak geçtiği için, zaten kesin bir zaman birimi söylemek çok da mantıklı değil.Tahmin etmek bütün olay. Ama tabi ki bu tahminlerin bir değer taşıyor olması ve bu değerin farkında olmak gerekli.

Yazılım projelerinde de “estimation” yapılması gereken bir olay. Yani müşteriye verilecek sözden ya da kontrattaki maddelerden ayrı olarak, yazılım geliştirme sürecinde, sürece katkı sağlayacak bir kavram. Yazılım geliştirirken hangi adımlarda ne kadar süre harcandığını görmekte, geliştirme sürecince görev dağılımın iyi yapılmasına katkı sağlayacaktır.

“Planing Poker”, olarak geçen poker planlaması tahmin süreçlerinin en basiti ve etkili yöntemi olduğunu düşünüyorum kendi tecrübelerimden. Agile(çevik) yazılım geliştirme metodlarında  tercih edilen bu yöntem aynı zamanda oldukça da zevkli…

Basit olarak poker planlaması, projedeki “item”ların ne kadar süre içerisinde yapılacağını interaktif bir şekilde tahmin ederek gerçekleşir. Bu süre kavramı belli bir puanlama sistemi ile yapılır. Normal sayısal değerlerin kullanılabileceği gibi Fibonacci sayılarının(0,1,2,3,5,8,13,21,34….) kullanılması tavsiye edilir. Bunun nedeni, Fibonacci sayıları ile yapılan tahminlerin daha anlamlı olabilecek olması. Şöyle ki;  “item” için tahmini olarak verilecek zaman yükseldikçe, o tahminin anlamı da aynı şekilde bulanıklaşacaktır.Yani bir “item”a 20 birim ya da 22,23 birim şeklinde bir zaman tahmini veriliyor olması birim değerinin yüksek olmasından dolayı çok da bir şey ifade etmez. 20,22,23 şeklinde değil de zaman biriminin “yüksek” olması şeklinde daha anlamlıdır. Aynı şey zaman biriminin düşük olarak tahminlendiği “item”lar için geçerli değildir. Düşük zaman tahmini şeklinde belirlenen “item”lar, farklı şekilde yorumlanarak önceliklendirme konusunda etkili olabileceklerinden dolayı yukarıdaki gibi yorumlanmamalıdır.Bu arada hep zaman birimi olarak bahsettim. Ama peki birim olarak ne kullanmak gerekli? Tahminleme yapılırken kullanılan zaman birimi,”saat” ve “gün” şeklinde projenin büyüklüğüne göre değişkenlik gösterebilir.Ya da uyguladığınız geliştirme metodolijisi içerisinde belli bir puan sistemindeki puana da denk gelebilir.

Poker planlamasının nasıl yapıldığına geçelim şimdide. Öncelikle tahminlemenin yapılacağı olan “item”lar açıklanır. Bu işi geliştirme sürecine hakim bir kişinin yapması en doğru olacaktır. Ürün yöneticisi ya da projeye hakim olan proje yöneticisi gibi birinin bu süreçte bulunuyor olması, “item”ların açıklanmasında faydalı olacaktır.Bunun amaçı tahminlemeden önce “item”ların tüm geliştiriciler açısından aynı şeyi ifade ediyor olmasıdır. “item”lar herkes için aynı şeyi ifade etmiyor ise ortaya çıkan tahminlerdeki tutarsızlıklar çok büyük olacaktır.”item”ların içeriğini netleştirmek için bu aşamada “item”ları alt maddeler(task) ile açıklıyor olmak faydalı olacaktır. Açıkcası “item”ların net olmasının, tahminlerin faydalı bir çıktı ortaya koymasında çok önemli olduğunu düşünüyorum.

“item”lar netleştikten sonra, herkes tahminin gizli olarak yapar. Bir kağıda yazmak, ya da bu iş için kullanılan kartları seçmek(-ki iskambil kartları ya da önceden hazırlanmış Fibonacci kartları faydalı olabilir)  koşulu ile tahminler yapılır. Tahminler yapılırken, kafa karışıklığına yol açmamak için bu işlemin gizli yapılması şarttır. Daha sonra aynı anda herkes tahminin gösterir.Tahminlerdeki zaman birimlerinden en büyüğünü ve en küçüğünü belirten kişiler, neden bu tahminlemeyi yaptıklarına dair kısa açıklamalarda bulunur. Bu sayede başkaları tarafından öngörülemeyen şeyler ortaya çıkar ve tahminleme tekrar aynı şekilde herkes arasında yapılır ve ortak bir karar ortaya çıkar.Bu süreç 2-3 adım olabilir. Ama zaten en fazla 3.adımdan sonra ortak bir şeyler ortaya çıkacaktır.

Bu şekilde tüm “item”lar tek tek tahminlenir. Ortaya çıkan sonuç sadece tahmin açısından değil, geliştirme sırasında yapılacak işlerin netleşmesi açısından da çok önemlidir. Poker planlaması, geliştiricilerin takım içerisinde kendilerini daha düzgün ifade etmesini ve en önemlisi takım içerisindeki iletişimin gelişmesini sağlar. Her takım elemanı, bireysel olarak kendi potansiyelinin farkına daha kolay varır.Neyse şimdilik bu kadar…Kendi tecrübelerim dahilinde bu konu hakkında doğru ya da yanlış bir şekilde bir şeyler paylaşmak istedim. Fikir ve düşüncelerinizi iletmekten çekinmeyin, ciddi anlamda önemli benim için…

Somasegar’ın yaptığı açıklama ile Visual Studio 2010 ve .NET Framework 4.0’ın bir kaç hafta geçikeceğini öğrenmiş olduk. Daha önce 22 Mart 2010’da çıkacağı söylenen VS 2010 ve .NET Framework 4.0’ın bu ötelenmesi, Beta 2’den sonra gelen faydalı feedback’ler olmuş.Nasıl yani derken,performans anlamında Beta 2’den sonra bir çok iyileştirme yapılmış ve yapılacakmışta. Bundan dolayı biraz ertelenmesi gerekiyormuş. Şubat 2010 gibi Visual Studio 2010 RC versiyonu ile bu iyileştirmeleri bizimle paylaşacak olan Microsoft kim bilir ne zaman çıkaracak RTM halini…