FELİPE

25/1/2009

Yeniden Düzenleme (Refactoring/alişan demira/felipe45@hotmail.co

Extreme programming yönteminin diger tasarım/kodlama yöntemlerinden büyük farkları vardir. Bunlardan en önemlisi, tasarım ne zaman ve ne kadar yapilacağıdır.

Bildiğiniz gibi eski tasarım yöntemlerinde, başta uzun sureli tasarım yapmak, ve ciltler dolusu tasarım belgesi ortaya çıkartmak gerekir. Bu fikre göre, bu devre icin ne kadar uzun zaman harcanırsa, o kadar iyidir.

Böyle projelerin başarı yüzdesi %50'dir. Sektörde bunun birçok örneğini gördük ve yaşadık.

Bu yüzden yeni seçenek olarak gelen her yöntem, ne kadar ve ne zaman tasarım yapılacağını tanımlamalıdır.

Elimizdeki silahlar

Teknolojide ve diğer birçok konuda, "çapımızı" elimizde olan yetenekler, bildiğimiz püf nokta gibi yararlı bilgiler belirler. Bu noktalara dayanarak çözüm üretiriz. O yüzden, XP yönteminin tasarıma yaklaşımı açısından, yeni bir 'numara' öğrenmek zorundayız. Bu numara 'yeniden düzenleme' denilen refactoring numarasıdır.

Yeniden Düzenleme

İlk once kabul etmemiz bir nokta: Hiç bir programcı bir defada kafasında kurduğu tasarımı, hiç değisiklik yapmadan kodlayıp ortaya çıkaramaz. Kafada kurulan tasarım ile, yazılan kod arasinda 'kodu yazarken' muhakkak bazı değişiklikler gerekecektir. Bunun sebeplerinden biri, kod yazmanın gerçekle yüzyüze gelinen yer olmasıdır, derleme yaptiğınızda sonuç ya, gecer ya kalır. Ayrıca, kodu yazarken daha ilginç 'tasarım fikirleri' aklınıza gelecektir. Bu gayet normal. Zaten tasarım/kodlama surekli bir davridaim icinde gecer, biri ötekini etkiler.

İşte bu yüzden, XP yöntemi tasarım surada baslar, surada biter, sonra kodlama baslar demez. XP'ye göre, programcı her zaman tasarım yapar, her zaman kodlar. XP programcısı için kodlamak bazen Lego gibi yap-boz ruhu ile uğrasılan, bazen çok ciddi bağlantıları kurulan bir ortamdır.

Daha uzatmadan, öğretecegimiz 'numaraya' gelelim. Yeniden duzenleme, adindan belli oldugu gibi, kodu yeniden duzenleyip tasarımını değistirmeye denir. Fakat bu oyle yapilir ki, programin değisim öncesi ve sonrasındaki özellik listesinde hiçbir değişiklik olmaz.

'Ozellik listesi niye degismez?' diye bir soru sorulabilir. Bunun cok pratik sebepleri var. En onemlisi sudur: Tasarım değişikligi program yapisini değistirdiği icin, değişimin dogru yapılıp yapilmadığının kontrolunun en rahat yolu özellik listesininin kullanıcı yüzünü kontrol etmektir. Hatta ve hatta daha iyisi, sanal bir kullanıcı sayılabilecek JUnit birim testlerinizi bu iş için kullanmaktır. (Zaten yazılma amaçları da budur). Yani, test programlarını degisimden önce ve sonra isletirsinizseniz ve testler, iki sefer de basari ile geçiyor ise, demek ki tasarım değişikliginiz yeni hatalar yaratmamış.

Boylece o hepimizin basina gelen, tasarım degistirken programa 'yeni hata ekleme' olayindan korunuruz.

Tekrar soyleyelim: Yeniden duzenleme teknigi icin test programlarinin varlığı ZORUNLUDUR. Bazı programcıların yeniden düzenleme tekniğinden uzak durma ve hatta secenek olarak bilmemesinin sebebinin altinda, test programı yazma disiplinindeki eksiklik yatar. Eger elinizde test programı yoksa, tasarım değişikliğinin doğru olup olmadığını nasıl anlayacağız?

Şimdi yeniden düzenlemenin ABC'sine, yani alt duzey tekniklerine gelelim: Bu tekniği uygularken yaparken amacımız şu olmalidir:

  • Kod içinde tekrar eden olguların merkezilestirilmesi, yani tek bir yerde toplanmasıdır.
  • İşlemlerin ait olduğu nesneler üzerinde toplanmasıdır.

Bir örnek yeniden düzenleme şöyle olabilir. Mesela, Araba adlı nesnemiz var, ve Araba nesnesini kalıtım (inheritance) ile uzatan Tofas adli nesnemiz. Bildiginiz gibi kalitim ile kalitim yaptiginiz nesnenin islemleri size gecer. Yani Tofas nesnesi, Araba nesnesinin butun islemlerini kullanabilir.

Simdi diyelim Serce adli bir nesne yarattik. Birden farkettik ki, Serce nesnesi ile Tofas arasinda benzerlikler var. Fakat Serce ile Tofas arasinda tek baglanti Araba nesnesi! Ortak olmasi gereken islem Araba uzerinde degil.

Bu gibi durumlarda, hemen acele bir yeniden duzenleme yapip, ortak olmasi gereken islemi Tofas nesnesinden, Araba nesnesine 'yükseltmemiz' gerekir. Bunu yapinca artik bu isleme Serce'den erismek mumkundur.

25/1/2009

Genel Yazılım Teknikleri/felipe45@hotmail.com/alişan demiral

Programcilik isinde temel bazi teknikler, her turlu yazilim turu icin gecerlidir. Baska bir yazimizda, genel yazilim tiplerinden bahsettik. Fakat bu cesitler icinde ortak "bazi" seyler vardir. Mesela tekrar tekrar kullanilan kod parcalari, kendi basina bir unite icine konursa, o halde kullanilmasi daha rahat olur.

Ortak teknikleri asagidaki grupta toplayabiliriz.

  • Ortak kodu ayirma
  • Dogru veri seklini bulma
  • Veri gizleme

Ortak kodu ayirma yukarida bahsedildi. Bir sonraki konu, dogru veri seklini bulmak; yani, her algoritma icin, dogru veri tarifini kullanmaktir.

Sorunun temeline inersek daha iyi anlayacaksiniz. Bu meslekte yaptigimiz ise "kodlama" denmesi raslanti degildir. Dil bir kodlamadir. Bazi seylere verilen bazi isimler, onlarin hafizasini cagristirir. Dil bir koddan ibarettir. Herneyse, bir programin icinde, "veri sekli" bir bakima kodlamadir. Mesela ZIP dosyalari icinde veri belli sekilde siralanmistir. XF harfleri BURAK kelimesine tekabul edebilir; veri o sekilde kodlanmistir. Bazi veri sekilleri duz yazida gosterilmeyecek sekilde karmasiktir, agac metodu (dal-budak) ayri bir veri saklama metodudur.

Her turlu problem icin, ayni veri seklini kullanmayin. Bazi problemlerin cozumu icin dal-budak sekli etkili olacaktir; bazi problemler anahtarli-dizi (hash array) ile daha rahat cozulur. Eger dogru veri seklini bulmussaniz, programlariniz birden bire daha cok rahatlayacaktir. Bunu hemen farkedeceksiniz. Yanlis veri sekli programinizi daha zorlastirir, ve surekli bogusmak zorunda kalirsiniz.

Bir diger yazilim teknigi, 'veri gizlemektir'. Bunu soyle ozetleyelim. Mesela programiniz icinde her degiskenin herkez tarafindan goruldugunu, ve degistirilir oldugunu dusunun. Eger bu program 400,000 satir kadar buyuseydi, ve her degisken herkez tarafindan gozukseydi, o zaman programin hangi kismi hangi degiskeni "degistirmis" katiyen anlasilmazdi.

Boyle bir programda hatalari bulmak imkansiza yakindir. Bu isin cozumu veri gizlemekten gecer. Yani, eger veri bir program kismina gerekli degilse, veri bu kisimdan gizlenir. Bu sayede programci rahat bir kafayla, hatalari bulurken daha az yere baksada olur. Sonucta degisken bolum ABC tarafinda yapilmamistir: Yapilamaz, cunku derleyici erismeye kalkan bolumler hakkinda hata ekrani verecektir.

 

25/1/2009

Yazılım Çeşitleri/felipe45@hotmail.com/alişan demiral

Yazilim cesitleri ve metodlari tek degildir. Bir metodu ogrenerek butun problemleri cozeceginizi sanmayin. Kariyerimiz boyunca "Rational Metodu", "Extreme Metodu" ogrenip Istanbul'u fethedecigini zanneden cok programci tanidik. Bu metodlar, her turlu yazilim problemine deva olacaklarini reklam ederler, fakat degisik yazilim problemlerinin ve cozumlerinin ne oldugunu bilmezseniz, hangi metodu ogrenirseniz ogrenin, basariya ulasamazsiniz.

Ana software "problem alanlarini" sayalim..

  • Internet "site" programlari.
  • "Anlik" calismasi gereken programlar.
  • Gunluk, "toplu" halde calisabilen programlar.
  • Gorsel Programlar

Butun bu problemlerin kendine gore "teknolojik" cozumleri vardir. Mesela, veri tabani paket programiniz Oracle; yani SQL dili kullanabileceginiz bir paket. Musteriniz dedi ki: "Bana oyle bir progrem yazki, her gun ABC kayitlarini isleyip XYZ kayidi haline getirsin. Ne kadar cabuk yapabilirse o kadar iyi. Sadece islesin. Gorsel falan hic bir sey istemem."

Yukaridaki program 'gunluk' program kategorisine girer. Boyle programlar surekli 'uyanik' durmak zorundadir, ve isleyecek veri beklerler. Sanki ac bir hayvan gibidirler, veri buldugu anda yerler. Yoksa gelmesini beklerler. Gorsel program orasina burasina klik edilsin diye bekler, o yuzden daha degisik programlama gerektirir.

Anlik programlarin degisik ihtiyaclari vardir. Mesela bir uzay mekigini kontrol eden, ya da son model arabanizda benzin pompasini ayarlayan program, anlik programdir. 1~2 milisaniye arasinda karar vermesi gerekir, o yuzden kod ona gere yazilir. Bilgisayarlar tabii ki herseyi yapabilecekleri kadar hizli yapmaya ugrasirlar, fakat birden fazla, ayni anda islem gerektiren olaylar oluyorsa, belki bazi seylerin birbirini beklemesi gerekebilir. Mesela benzin pompasi dogru olcude benzin vermekle gorevlidir, ama ayni anda fren sinyallerini dinleyen bir bolumude vardir. Fren sinyali geldigi anda herseyi birakmasi mecburdur. Bunlar "anlik" program problemleridir. Gunluk programlarin problemleri yukarida gordugunuz gibi degisik.

Site programlari bir baska hikaye: Internet siteleri ayni anda birden fazla kisiye hizmet versin diye yazilir. Yani, ayni anda degisik kullanicilara hizmet verir, ama bu isler aslinda birbirinin kopyasidir, ve kullanicilar birbirlerini "aninda" etkileyemezler. "Anlik" program kategorisine bu yuzden benzemesine ragmen, aslinda cok ayri bir metod gerektirirler. Mesela amazon.com sitesine girdiniz, uye oldunuz, kitap satin aldiniz. Fakat ayni anda, amazon.com sitesinde ayni islemleri yapan belki binlerce kullanici vardir. O kullanicilarin yaptiklari sizi etkilemez, herkes sanki kendi odasinda, izole bir sekilde isini yapmaya ugrasir. Bu tip programlar "kapasite" icin yazilirlar, problemler veri tabanina daha hizli erisim, sayfa hizli yukleme gibi seyler etrafinda doner. Son zamanin Internet Java paketleri, sanki siteleri bir kisi icin yaziyormus gibi yardim eder size; ondan sonra kopya kagidindan cikarmis gibi 10,000 kisi icin ayni kodu kullanabilirsiniz.

Gorsel programlar Windows programlari gibidir. Unlu windows 'fal' oyunu bir gorsel programdir. Klik edilebilen nesneler vardir, bu nesnelerin bazilari her zaman kliklenemez, kullanici hatasi verilir bu zamanlarda, yada kullanici o isi yapamaz. Bu tip programlarin temelinde bir 'hadise/vaka dongusu' vardir. Bir gorsel hadise oldugu anda, (nesne uzerine klik) hadise icin yapilan gorevler teker teker, onceden programa kayitlanir. Bu stili ilginc yapan, programi tamamen 'gorsel hadiseler' uzerine kurulmasidir. Oteki tip programlarda sanki duz bir sira yoktur. 'Su olursa sunu yap, bu olursa bunu yap' seklinde programlardir.

25/1/2009

C#.Net ile Nesneleri Sıralama ve IComparable,IComparer Kullanımı

Birden fazla nesnenin sıralabilmesi için nesnelerin karşılaştırılabilir olması gerekir. Örneğin bir sayı diğer sayıdan ya daha büyüktür, ya daha küçüktür yada eşittir. Bu karşılaştırılabilme bilgisi sayesinde bir int dizisi sıralabilir. Aynı karşılaştırma özelliği string içinde geçerlidir. "Ali" her zaman "Zafer" den önce gelir. Alfabetik sıra karşılaştırma kuralını bize verir. Peki yarattığınız herhangi bir class'ın birden fazla nesnesini nasıl sıralarsınız. Örneğin Person adlı bir class'ınız var. Elinizde 5 tane Person nesnesi var. Bu nesneleri nasıl sıralıyabilirsiniz. İşte bu yazının konusu bu.

Nesnelerin Sıralanması

int,string gibi basit tiplerin compareTo(object o) method'ları bulunmaktadır. bu method verilen diğer tip ile nesnenin kendisini karşılaştırması için kullanılır. Örneğin:

int i=4;
int sonuc=i.compareTo(5);

şeklinde kullanılabilir. i sayısı 4 5'ten küçüktür. Dönen sonuç negatif bir sayı olur. Dönen sayıdan iki sayının hangisinin büyük olduğu veya iki sayının eşit olup olmadığı anlaşılır. comporeTo'da şu kural geçerlidir.

Eğer verilen sayı büyükse sonuç:negatif
Eğer verilen sayıs küçükse sonuç:pozitif
İki sayı eşitse sonuc: 0

compareTo methodundan dönen sonuç ile iki sayıyı karşılaştırmış olursunuz.

compareTo en çok sıralama işleminde kullanılır. Örneğin bir dizideki tüm elemanlar birbirleriyle karşılaştırılarak sıralama yapılır. Örneğin bir int dizisi aşağıdaki gibi sıralanabilir.

int[]a=new int[]{4,5,1,5,2,3};
Array.Sort(a);

artık a dizisi küçükten büyüye sıralanmış olacaktır.

Eğer kendi yaptığınız bir class'ın nesnelerini sıralamak istiyorsanız IComparable interface'ni kullanmanız gerekir. IComparable bir interface'dir ve sadece tek bir methodu vardır: compareTo(object o). Yaptığınız class bu interface'si implement edecek ve compareTo methodunu dolduracak. Aşağıda bir Person class'ı bulunmakta. Bu class ad,soyad ve yaş degiskenlerini içermekte. Bir Person dizisi sıralandığında yaşa göre sıralanmasını istiyoruz. Aynı yaşta olanların ada göre, adlarıda aynı olanların soyada göre sıralanmasını istiyoruz.

Person.cs<_script /><_script /> İndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace TestApp
  3 {
  4   public class Person : IComparable
  5   {
  6     private string ad;
  7     private string soyad;
  8     private int yas;
  9     public Person(string ad,string soyad,int yas){
 10       this.ad=ad;
 11       this.soyad=soyad;
 12       this.yas=yas;
 13     }
 14     public string Ad{
 15       get{return ad;}
 16     }
 17     public string Soyad{
 18       get{return soyad;}
 19     }
 20     public int Yas{
 21       get{return yas;}
 22     }
 23     public int CompareTo(object obj)
 24     {
 25       Person p=(Person)obj;
 26       int sonuc=yas.CompareTo(p.Yas);
 27       if(sonuc==0){
 28         sonuc=ad.CompareTo(p.Ad);
 29         if(sonuc==0){
 30           sonuc=soyad.CompareTo(p.Soyad);
 31         }          
 32       }
 33       return sonuc;
 34     }
 35     public override string ToString(){
 36       return Ad+" "+Soyad+" : "+Yas;
 37     }
 38   }
 39 }

Görüldüğü gibi Person class'ı IComparable interface'sini implement etmiş ve compareTo method'nu yazmış. Önce verilen object Person'a cast edilir. Önce yas karşılaştırılır. Eğer yaşlar eşitse sonuç gönderilir. Eğer yaşlar eşitse bu sefer ad kontrol edilir. Eğer adlarda eşitse soyada bakılır. Aşğıdaki basit bir test uygulaması yapılmıştır.

TestApp.cs<_script /><_script /> İndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace TestApp
  3 {
  4   public class TestApp
  5   {
  6     public static void Main(string[] args){
  7       Person[] persons=new Person[5];
  8       persons[0]=new Person("Ali","Yılmaz",10);
  9       persons[1]=new Person("Veli","Yılmaz",13);
 10       persons[2]=new Person("Ali","Kaya",13);
 11       persons[3]=new Person("Mehmet","Kaya",10);
 12       persons[4]=new Person("Mehmet","Yılmaz",11);
 13       Array.Sort(persons);
 14       for(int i=0;i.Length;i++){
 15         Console.WriteLine(persons[i]);
 16       }
 17     }
 18   }
 19 }

Sıralama yapıldıktan sonra aşağıdaki sıraya göre ekrana basılacaktır.:

Ali Yılmaz : 10
Mehmet Kaya : 10
Mehmet Yılmaz : 11
Ali Kaya : 13
Veli Yılmaz : 13

 

Nesnelerin Birden Fazla Değişik Şekilde Sıralanması

Nesnelerinizi birden fazla değişik şekilde sıralamak isteyebilirsiniz. Örneğin Person'ları adlarına göre sıralamak isteyebilirsiniz. IComparable sadece bir şekilde sıralamanıza izin veriyor. Değişik şekilde sıralama yapmak istiyorsanız IComparer interface'ni kullanmanız gerekir.

Person class'ına bir inner class ekleyelim. Bu class IComporer'i implements etsin.

 

public class ComparerByName : IComparer{
	public int Compare(object o1,object o2){
		Person p1=(Person)o1;
		Person p2=(Person)o2;
		int sonuc=p1.Ad.CompareTo(p2.Ad);
		if(sonuc==0){
			sonuc=p1.Soyad.CompareTo(p2.Soyad);  
		}
		return sonuc;					
	}
}

 

Yukarıda görüldüğü gibi karşılaştırma önce ada sonra soyada göre yapılıyor. Şimdi diziyi ada göre sıralamak için Array classının sort methodu aşağıdaki gibi çağrılır:

Array.Sort(persons,new Person.ComparerByName());

sort methodunun IComparer alan bir versiyonuda bulunmaktadır. Böylece persons dizisi ada göre sıralanmış olur.

Dosya Listesi

25/1/2009

Net'te Attribute Kullanımı/felipe45@hotmail.com/alişan demir

Attribute Nedir ?

Attribute'ler çalışma ortamına (runtime ortamı) bilgi vermek için kullanılan etiketlerdir. Attribute'ler herhangi bir method,class,struct vs.. hakkında bilgi verebilir. Bu yazıda C#.NET'te attribute'lerden bahsedilecektir.

Bir Attribute [ ] parantezleri içerisinde yazılırlar. Attribute'lerin parametreleri olabilir. Bu paramtreler fonksiyonlardaki gibi , ile verilebildiği gibi isim=değer şeklinde de verilebilir.

 

[attribute(paramtre1,paramtre2,..)]

 

veya

 

[attribute(paramtre1=deger1,paramtre2=deger2)]

 

şeklinde verilebilir.

Attribute'ler etkiledikleri elementin hemen üstünde tanımlanırlar. Bir elemente birden fazla attribute uygulanabilir.

Koşul (Conditional) Attribute'leri

Bu tür attribute'ler genellikle debug veya test için kullanılmaktadır. Örneğin bir method'un sadece debug ederken çalışmasını sağlayabilirsiniz.

 

[Conditional ("DEBUGGING")]
public static void MyMethod( ){
    ...
}

 

burada DEBUGGING define edilmiş bir semboldur. Eğer bu sembol #define DEBUGGING şeklinde tanımlanırsa myMethod kullanılabilir. Tanımlanmassa myMethod çağrılsa bile dikkate alınmaz. Çünkü Conditional ("DEBUGGING") ile DEBUGGING sembol'ünün tanımlanması gerekir.

DllImport Attribute

Bu attribute unmanaged code (CLE standartları dışında yaratılan kod- .NET kullanılarak yaratılmamış diyebiliriz) ile yaratılmış bir dll'deki method'ları kullanmaya yarar.

 

[DllImport("foo.dll", EntryPoint="MyFunction")]
public static extern int MyFunction(string parametre1); 

 

şeklinde tanımlanır. Bu attribute'nin kullanılması için System.Runtime.InteropServices çağrılmalıdır. MyFunction method'unu kullanacağımızı belirtiyoruz. Hemen altında da method'u tanımlıyoruz. Kullanırken de normal bir method çağırır gibi çağırıyoruz.

 

int a=MyFunction("test");

 

DllImport ile system native kodlarını kullanabiliyorsunuz. Örneğin bip çaldırabilir, ekranın print screen'ini alabilir, desktop'taki saati değiştirebilirsiniz. Sonuç olarak dllimport kernel32.dll,user32.dll gibi windows dll'lerine erişmenizi sağlar.

Custom Attribute'ler- Kullanıcının yarattığı attribute'ler

Bir attribute yaratmak için system.Attribute class'ını extend etmeniz gerekir. AttributeUsage ile de yarattığınız attribute'nin neler(Method,Class,Struct vs) üzerinde etkili olacağını söylemeniz gerekir.

 

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute: System.Attribute{
 ... 
}

 

Yukarıda görüldüğü gibi bir MyAttribute class'ı yarattık. [AttributeUsage(AttributeTargets.Method)] ile de bu attribute'nin method'ları etkileyeceğini söylüyoruz. Attribute'lere isim=deger şeklinde paramtre vermek istiyorsanız isim property'isini yaratmanız gerekir.

 

public string Isim{
	get{return isim;}
	set{isim=value;}
}

 

Bir class'ın Metadata'sını inceleme

Metadata bir class'ı oluşturan birimler hakkındaki bilgilere denir. Bir class'ın attribute'leri hakkında bilgi edilinebilir. Önce class'ın bilgisi alınır. Bunun için MemberInfo class'ı kullanılır.

 

using System.Reflection;

...

MemberInfo typeInfo=typeof(MyClass); 

 

daha sonra tüm attribute'lere erişilebilir.

 

object[ ] attrs = typeInfo.GetCustomAttributes(false);
« Önceki ::