Memik Yanık - Kişisel Web Sitesi Ana Sayfa | Hakkımda | Kitap Önerileri | Fotoğraflarım | RSS RSS | İletişim

Genel

Programcılar İçin Yazarlık Dersleri - 3


Hata Yakalama ve Exception Sınıfları’nı Nasıl Anlattım? 

Bu makalede programcılık üzerine yazanlara, öğrencilere programcılık öğretenlere ve kendi başına programcılık öğrenenlere hitap etmeye çalışılmaktadır. Bu bölüm okunduktan sonra programcılık üzerine yazılan bazı metinlerin neden zor okunduğunu, neden anlaşılmaz olduğunu fark edeceksiniz. Bu derste hem genel konular üzerine konuşacağız hem de C# 3.0 kitabımdan aldığım Hata Yakalamak ve Exception Sınıfları makalesini Yazarlık Dersleri bağlamında ele alacağız, neyi neden nasıl anlattığımın hesabını vereceğim. Başka bir deyişle C# 3.0 kitabım için hazırlayıp sonra kişisel web sitemde konunun meraklılarıyla paylaştığım 30 sayfalık metni bu bölümde ele alacağım. Programcılık üzerine yazanlar bu metni dikkatlice okuduktan sonra dönüp daha önce yazdıklarına burun kıvıracaklarına, ilk fırsatta yazma ve anlatma stillerinde köklü değişikliklere gideceklerine inanabilirsiniz. 

Memik Yanık’ın İlk C# Kitabı 

Bu derste asıl konumuz Hata Yakalamak ve Exception Sınıfları bağlamında programcılık kitaplarını nasıl kaleme aldığımı anlatmak olduğundan konudan uzaklaşmamak için kendi C# kitaplarıma dönüyorum. 2004 yılında yayınlanan C# kitabım içerik bakımından ortalama bir kitaptı. Yani C# ve .NET programcılığına henüz başlayanları belli bir düzeye çıkarmayı hedefliyordu. Bu hedefin içinde veritabanı uygulamalarını geliştirebilmek, API fonksiyonlarını kullanabilmek, basit web servisi yazabilmek bile vardı. Başka bir deyişle 900 sayfalık kitapta çok sayıda konuya yer yermeye çalışmıştım. Böyle olunca kitaptaki bazı konular ayrıntı içermiyordu. Örneğin yukarıda sözünü ettiğim makalede anlattığım konu, yani hata yakalama konusu topu topu 7 sayfaydı. Tabii ki 900 sayfalık bu kitap bazı okurlar için gerek duymadığı konuları içerirken bazı okurların asıl gerek duydukları konular yoktu veya yeteri ayrıntıda anlatılmamıştı. 

Sözünü ettiğim kitapta 7 sayfa boyunca anlattığım Hata Yakalamak adlı bölümde sıfıra bölme hatasından söz etmiştim. Çünkü sıfıra bölme programcılık derslerinin mutlaka anlatılan klasik hatalarından birisidir. Yoksa serileştirme yapılırken karşılaşılan hatalardan söz edecek değildim. Çünkü serileştirme işlemi iyice anlatılmadan serileştirmeyle ilgili hataları veya Application Domain’e assembly yüklerken karşılaşılan hataları yakalayıp anlatmak anlamsız olurdu. Aslında bazılarınız “madem her kitapta sıfıra bölme hatasından söz ediliyor siz de başka hatalardan söz edin” diyebilirler. 

Bu uyarıyı yapan arkadaşlara cevabım hazır: Yukarıda sözünü ettiğim ilk C# kitabım yayınlandıktan çok sonra birileri çıkıp “ey memik yanık sen sıfıra bölme hatasını biliyor olamazsın” demesin mi? Yani 1994 yılından bu yana sayısız programcılık kitabına imza atan memik yanık sıfıra bölme hatasından bi haberdir diye düşünenler varken sizler kalkıp bu konu gereksizdir, C#’la ilgilenen herkes zaten sıfıra bölme hatasını biliyordur diyorsunuz. Otoritelerin(!) "Memik Yanık sıfıra bölme hatasını bilemez" görüşünden yola çıkarak C# 3.0 kitabımda hata yakalama konusuna torpil geçip(tabi başka konuların sayfalarından kısarak) şimdiye kadar Türkçe yayınlanmış C# kitapları bağlamında bu kitabımın “Hata Yakalamak” konusunun en kapsamlı anlatıldığı kitap olmasını hedefledim. 

Şimdi birileri çıkıp “ey memik yanık hata yakalamak konusunda “en” kapsamlı bölümü yazmış olman yazdıklarını bildiğine delalet olmaz, hata yakalamak konusunda bilgi verirken hazırladığın 3-5 satırlık kodlarda kullandığın değişkenlere veya metotlara ad seçerken başka yerli yazarların kitaplarından “izinsiz” esinlenmediğini nereden bileceğiz” diye soru yöneltirlerse? Tam bu sırada ortaokul 3. sınıfta okurken tarih hocam aklıma geldi. Tarih dersinde pek iyi değildim. Baktım tarihten kalacağım, oturup biraz çalıştım. Son yazılı sınavda soruların hepsine cevap verip çıktım. Ertesi gün hocam beni tahtaya çıkarmıştı ve yazılıda sorduğu soruları bir de tahtada cevaplamamı istemişti. Benzer cevapları tahtada da verince bana tam puan vermişti ve kopya çekmediğime inanmıştı. Şimdi benzer çalışmayı yukarıda sözünü ettiğim Hata Yakalamak ve Exception Sınıfları makalesi için yapacağım. Başka bir deyişle bu makalede veya C# kitabımda yazdıklarımı bildiğimi kanıtlamaya, verdiğim örneklerde kullandığım değişkenlere, metotlara çalıntı yapmadan ad bulabilme becerisine sahip olduğuma, 2 sayıyı bir birine bölen C# kodu yazabildiğime sizleri inandırmaya çalışacağım. Tabii bunu yaparken konuları nasıl anlattığımı, hangi örneği neden verdiğimi vs tek tek anlatacağım. 

Hata Yakalamak mı Hata Ayıklamak mı? 

Her ne kadar C# 3.0 kitabımda Hata Yakalamak ve Hata Ayıklamak konularını ayrı birer bölüm olarak düzenlemiş olsam bile bu sitede sizlerle paylaştığım makalede hataları ayıklamaktan ve projeleri çalıştırmaktan kısaca söz ettim. Çünkü Visual Studio kullanan bir çok programcı adayı uygulamaların Debug ve Release modlarından çok sonra haberdar olabilmektedir. Entegre hata ayıklayıcısı ile ilgili olarak yapılmış ayarlamalardan Debug veya Release moduna göre Exception sınıflarının verdikleri tepkiler değiştiği için kısaca olsa bile Debug nedir, Release modu nedir sorularına cevap vermeye çalıştım. Bu düşünce ile bölümde bir sayfa boyunca dedikodu yaptıktan sonra “Projeleri Çalıştırmak” adında bir başlığa yer verdim.
 

Bazılarınız hemen “ey memik yanık bizlere projelerin nasıl çalıştırıldığını anlatmak için mi bu kadar hikâye okuttun?” diye tepki gösterebilirler. Bu soruyu soran arkadaşlara Visual Studio’nun menülerini tek tek dolaşıp Start veya Run adında bir komutun olup olmadığını araştırmalarını önermek isterim. Bir iki dakikalık araştırmadan çıkacak sonuç şu olabilir: Debug menüsünde Start Debugging adında bir komut var ve Standard araç çubuğunda bu komutu temsil eden bir düğme bulunmaktadır. 

Hemen sorumuzu soralım: Programcı üzerinde çalıştığı uygulamayı neden çalıştırmak ister? Cevap basittir ve nettir: Uygulamayı test etmek, varsa hataları ayıklamak için. İşte bu ihtiyaçtan yola çıkan Microsoft’un programcıları Visual Studio’nun menü çubuğunda Debug adında bir menüye yer verip bu menüde Start Debugging komutunun olmasına karar vermişlerdir. Makalede Debug ve Release modlarından söz ederken aşağıda verdiğim ekran görüntüsünü kullandım.



Bu ekran görüntüsünü kullanmamın nedeni üzerinde çalışılan uygulama Start Debugging komutu ile çalıştırıldığı zaman geri planda nelerin olduğunu, hazırlanan EXE dosyanın nereye konulduğunu okura göstermektir. Şimdi bazı arkadaşlar bu ekran görüntüsü makale veya kitapta fuzuli yer işgal etmez mi, bu ekran görüntüsünü kitapta kullanmakla kitabı şişirmiş olmuyor musun diye sorabilirler. Elbette bu ekran görüntüsü verilmese bile Visual Studio ile C# uygulaması geliştirmek isteyen kişi bir süre sonra Debug klasörüne konulan EXE dosyayı bir şekilde fark eder. Ancak bu fark etmenin anlamlı olması için aynı zamanda Bin klasörünün altında hazırlanan Release klasöründen de haberdar olması gerekir. Ötesi EXE dosyanın ne zaman Debug klasörüne, ne zaman Release klasörünü yerleştirildiğini bilmesi gerek. 

Bu ekran görüntüsünü kullanmanın amacı Visual Studio tarafından hazırlanan EXE dosyanın yerini göstermekten öte okurun konu üzerinde düşünmesini sağlamaktadır. İşini ciddiye alan yazar okurunun kafasından geçmesi muhtemel soruları öngörüp tam zamanında bu soruları cevaplar. Eğer yazar okurunun neyi bilip neyi bilmediği konusunda çok sık yanılırsa kitabı bazı okurlar için anlaşılmaz ve eksik olarak değerlendirilirken bazı okurlar için “bu kitabın düzeyi bana göre değilmiş” yorumu yapılır. Yine konu gelip hedef okur grubunu doğru seçip kitabın içeriğini ve anlatım tarazını ona göre seçmeye dayanıyor. 

Daha açık anlatımla Hata Yakalama veya Exception sınıflarını anlattığınız kişinin Release veya Debug modu nedir, Visual Studio’nun Configure Manager diyalog kutusunda neler ayarlanır, bu ayarların etkileri ve işlevleri nelerdir sorularına cevap verebiliyor olması gerekir. Bu konuların anlatıldığı kişi veya okur bu sorulara cevap veremiyorsa Exception sınıfları ilgili olarak anlatılanlardan “hiç bir şey anlamaz” denilemez ama kafasında oluşan bazı sorular cevaplanmamış olur. 

Okurun kafasında daha sonra cevaplanmak üzere(belki de hiç cevaplanmayacak) ertelenen soruların sayısı arttıkça yazılan metni okumak zorlaşır. Elbette kitabın ilk sayfasında sözünü ettiğiniz bir kavramı hemen orada anlatın demiyorum ama anlatmayacağınız veya çok sonra anlatacağınız kavramlardan mümkün mertebe söz etmemek gerekir. Örneğin birçok yerli yabancı yazar kitaplarının daha ilk sayfalarında Assembly, Application Domain, Process, Unmanaged Code vs.. daha birçok kavramın adını anarlar, birer cümle ile anlatmaya çalışırlar. Bana sorarsanız C# ve .NET Framework konusunda henüz yolun başında olan(zaten yolun başında olduğu için gidip kitap alıyor) okur için Application Domain veya Assembly’den birer cümle ile söz etmenin hiçbir yararı yoktur. Bırakınız yararı bazı temel kavramların 2-3 cümle ile anlatılması okurun kafasını karıştırıyor. Çünkü Assembly ve Application Domain gibi kavramlar hem ilk öğrenilmesi gereken konular değildir hem de en azından 15-20 sayfa boyunca anlatılması gereken konulardır. Yazar arkadaşlara bu konuda önerim şudur: Kitabınızın veya makalenizin hemen başında 2 cümle ile anlatmaya çalıştığınız kavram mutlaka bilinmeli midir? Bu soruya cevabınız evetse okurun o konuyu anlaması için ne gerekiyorsa hemen orada yapın. Okurun söz konusu kavram veya konuyu hemen öğrenmesi gerekmiyorsa ondan söz etmeyin. Ne zaman ki o konuyu ayrıntılı inceleyeceksiniz o zaman söz edin.

Try-Catch Blokları 

Projeleri çalıştırmaktan ve hataları ayıklamadan kısaca söz ettikten sonra sıra geldi kullanıcının çalışma anında yapması muhtemel hataları öngörüp tedbir almaya. Aslında benzer konuyu birçok kaynakta bulmak mümkündür. Zaten anlatılanlara fazla yabancı olmayan okur metni şöyle bir tarayıp verilen kod örneklerine bakar ve 3-5 satırlık kodlar kendisine yabancı değilse metni okumayı bırakır. Bu nedenle programcılıkla ilgili herhangi bir konu anlatılırken okurun o konudan bi haber olduğunu ve bilgisinin kitabınızın önceki sayfalarında yazılanlarla sınırlı olduğunu varsaymak zorunluluğu vardır. 

Ötesi okura bilmediği bir konuyu anlatılırken bilmediği başka bir konuya gönderme yapmamak gerekir. Örneğin C# kitabımda ve sözünü ettiğim makalede kullanıcı kaynaklı hataların yakalanması işleminin try-catch-finally blokları ile nasıl yapıldığını kısaca işaret ettikten sonra aşağıdaki gibi 2 cümle yazıp kısa bir kod verdim. C# 3.0 kitabımın Hata Yakalamak ve Exception Sınıfları adlı bölümünden yaptığım alıntıları italik yaptım. 

Kullanıcıdan bir işlem için tarih istediğinizi varsayalım. Kullanıcı TextBox’a tarih olarak değerlendirilemeyecek bilgi girerse programın çalışması kırılabilir. Aşağıda verilen metot işletil­di­ğinde TextBox’ın içeriği dönüştürülüp DateTime tipindeki değişkene aktarılır.

private
void textBox1_Leave(object sender, EventArgs e) 
 
   DateTime Tarih; 
   Tarih = Convert.ToDateTime(textBox1.Text);    
 }

Kullanıcı TextBox’a tarih veya zaman olarak değerlendirilebilinecek bilgi girdiği sürece bu kod hatasızca çalışır. Ne zamanki kullanıcı tarihsel tipe dönüştürülemeyecek bilgiyi TextBox’a girip başka nesnenin üzerine giderse bu kod hata verir ve program çalışması kırılır. 

Tabii ki bu kod son derece basittir ve okur her şartta DataTime’ın bir veritipi olduğunu fark eder. Ötesi ToDataTime() metodunu ilk kez gören birisi bile bu metodun işlevini yazarın desteği olmadan da anlar. En ideali madem hata yakalama işlemini anlatıyoruz ve okurun kitabı ilk sayfadan itibaren okuduğunu varsayıyoruz, bu kısacak kod verilmeden çok önce okurun DateTime yapısı hakkında bilgi sahibi olması gerekir. Başka bir deyişle Hata Yakalama bölümünden önce kitapta tarih ve zaman bilgileri üzerinde yapılabilinen işlemlerin anlatılmış olması gerekir. 

Ya C#’ta hata yakalama işleminin try-catch blokları ile yapıldığını söyledikten hemen sonra veritabanlarına özel bir hatadan söz etmiş olsaydım? Kitapta hata yakalama konusu veritabanı işlemlerinin anlatıldığı bölümden sonra olsaydı bu tercih bir soruna neden olmazdı. Bu nedenle kitaplarda yeni bir konuya geçildiğinde yazılanların kolay anlaşılmasını sağlamak için örnekler herkes tarafından bilinen bir konu veya işlemden yola çıkılarak hazırlanır. Bazı kitap ve makalelerde öyle karmaşık örnekler veriliyor ki okur anlatılan konuyu anlamaktan öte verilen örneğe kafa yormak zorunda kalıyor. 

Madem hata yakalamayla ilgili olarak verdiğimiz kısa açıklama ve 2 satırlık kod 3-5 saniyede okunup anlaşılacak basitliktedir hemen bu koda try-catch bloğunu monte edebiliriz. Tekrarlamak gerekirse aşağıda verilen kodun benzerini her yerde bulmanız mümkündür. Arada bir fark varsa o da catch anahtar kelimesinin kullanıldığı satıra burada bir şey yazılmamış olmasıdır. Dolayısıyla bu 3 satırlık kodu birileri sahiplenirse, birileri çıkıp fikrimi çalmışsın derse ona gülümsemeyi ihmal etmeyin. 

private
void textBox1_Leave(object sender, EventArgs e) 
 
   DateTime Tarih; 
   try 
   
      Tarih = Convert.ToDateTime(textBox1.Text); 
   
   catch 
   
      MessageBox.Show("Girdiğiniz tarih veya saat yanlış"); 
      textBox1.Focus();  
   
  } 

Konu hakkında az çok bilgisi olanların tahmin edeceği gibi bu kod işletilip ilk TextBox’a uygun tarih girilmeyip ikinci TextBox’ın üzerine gidilirse FormatException denilen yani string bilginin DateTime tipine dönüştürülememesi hatası ile karşılaşılır. Ancak başlangıçta okura meydana gelmesi muhtemel hatanın C# derleyicisinin nazarında hangisi olduğunu anlatmayı tercih etmedim. Başka bir deyişle ilk başta amacım try-catch bloğunun nasıl işlediğini göstermek olduğu için bir çok yazarın aksine catch deyiminin kullanıldığı satıra başka bir şey yazmadım. Çünkü aynı anda hem Exception sınıflarını hem de try-catch bloğunun işleyiş şeklini anlatmak istemedim. Çünkü amacım konuları birbirinden yalıtıp okurun ilk okumada yazılanları anlamasını sağlamaktır. Bir çok yazar arkadaşın kolay okunma bağlamında yaptıkları en büyük yanlış, okurun bilmediği birden fazla konudan veya işlemden aynı anda söz etmeleridir. 

Yukarıda verdiğim kısacak kod hakkında ek bir cümle etmek istiyorum: Kullanıcı çalışma anında ilk TextBox’a ister bir şey yazmadan, isterse de tuttuğu futbol takımının adını yazıp öyle 2. TextBox’a geçsin aynı hata, yani FormatException hatası meydana gelir.

Exception Sınıfları 

Okura böylelikle try-catch bloklarının nasıl işletildiğini işaret ettikten sonra Exception Sınıfları kavramına geçilebilir. Ancak ben tercihimi başka türlü yaptım. Konunun başına dönüyorum ve yukarıda verdiğim koddaki try-catch deyimlerini silip hata meydana geldiği zaman projenin çalışmasının sona erdirilmesini sağlayacağım 

Bazı kaynaklarda konu try-catch olduğunda release ve debug modları hakkında bir iki cümle yazılmış olsa bile kimse okurun merakını gidermeyi tercih etmiyor. Eğer kurduğunuz cümleyi okuyan veya verdiğiniz örneği inceleyen okurun kafasında neler geçer, neleri merak eder vs gibi soruları kendisinize sorup bu sorulara kendinizce cevaplar vermiyorsanız yazdığınız metin Microsoft’un MSDN’deki metinlerden bir farkı olmaz. Başka bir deyişle yazdıklarınızda help metni tadı olur. 

Kullanıcı yukarıda verdiğim kısa koddaki try-catch bloklarını kaldırıp(yani hata yakalayan satırları kaldırırsa) projeyi entegre debugger’dan bağımsız çalıştırırsa ne olur? Başka bir deyişle Start Debugging veya Build menüsündeki komutlar sayesinde hazırlanan EXE dosyayı Visual Studio’dan bağımsız çalıştırmak isterse ne olur? 

Tabii ki okur projesini Visual Studio’nun Start Debugging komutu ile çalıştırıp formdaki ilk TextBox’a geçerli bir tarih bilgisini girmeden bir sonraki TextBox’ın üzerine giderse Debugger projenin çalışmasını durdurur. Ancak programcı hiçbir tedbir almadan formdaki ilk TextBox’ın Leave olayını temsil etmesi için aşağıdaki gibi bir metot hazırlayıp sonra projesini Visual Studio ile gelen entegre debugger’dan bağımsız çalıştırırsa ne olur? 

private
void textBox1_Leave(object sender, EventArgs e) 
 
   DateTime Tarih; 
   Tarih = Convert.ToDateTime(textBox1.Text);    
 }

Bu konuyu neden mi uzattım: Cevap açık, henüz yolun başında olan programcı projesini hazırlayıp kullanıcıya teslim ettiğinde Visual Studio ile gelen entegre debugger’ın olmayacağını ve hatalar karşısında programının farklı tepkiler verebileceğini bilmesi gereklidir. Bu nedenledir C# kitabımın bu bölümünde aşağıda verilen 2 paragrafa ve 2 ekran görüntüsüne yer verdim. 

Build menüsünden Build komutunu verip üzerinde çalıştığım projeyi derledim. Daha önceki konulardan bildiğiniz gibi Build menüsünden komut verilip üzerinde çalışılan proje derlendiğinde Debug modunda iken hazırlanan EXE dosya “\bin\debug” klasörüne, Release modunda iken derleme yapıldığında ise EXE dosya “\bin\release” klasörüne konulmaktadır. Derleme işlemini yaparken Release modunda olduğum için derleme sonucu hazırlanan EXE dosya “\bin\Release” klasörüne yerleştirildi.



Bu klasördeki EXE dosya çift tıklanıp proje çalıştırılıp TextBox’a girilen bilginin tarihsel bilgiye dönüştürülmesi sırasında hata meydana gelmesi sağlanırsa ekrana aşağıda verdiğim diyalog kutusu gelir. Kullanıcı bu diyalog kutusundaki Continue düğmesini tıklayıp hatanın atlanılıp göz ardı edilmesini sağlayabilir veya Quit düğmesini tıklayıp uygulamanın çalışmasını sona erdirebilir. Meydana gelen hata hakkında ayrıntılı bilgi edinilmek istendiğinde ise Details düğmesi tıklanır.



Davrandığı hatırlatıldıktan sonra sıra hata yakalama sınıflarını anlatmaya geldi .NET Framework ile gelen hata yakalama sınıfları konusunun değişik boyutları olduğu için hata üretmesi muhtemel farklı kodlar yazıp aynı konuyu tekrarlama yoluna gittim. Bu düşünce ile forma bir ListBox yerleştirip aşağıda verdiğim kodu yazdım.

string[] takimlar = new string[5];
int adet = listBox1.Items.Count;
for (int i=0; i<adet; i++) 
   takimlar[i]=listBox1.Items[i].ToString(); 

Bu kodun anlaşılmaz bir yanı yoktur. Tabi bu değerlendirmeyi bu kitabın hata yakalama konusunun anlatıldığı sayfalardan öncesini okumuş olanlar için yapıyorum. Bu kodda önce 5 elemanlı string bir değişken tanımlanıp devamında for döngüsü ile mevcut ListBox’ın mevcut elemanları bu dizi değişkene aktarılmaktadır. 

Yukarıda okurun karşılaşmasını istediğim FormatException hatasından başka programcıların sık yaptıkları hatalardan bir diğeri dizi değişkenlerde ve indeksleyicisi olan sınıflarda yapılan IndexOutOfRangeException hatasıdır. Madem bu hata sık yapılıyor üzerinde durmak gerekiyor. Kitabımda hataya neden olması muhtemel bu kodu aşağıdaki gibi try-catch bloğuna aldım. 

private
void Form1_Click(object sender, EventArgs e) 
 
   string[] takimlar = new string[5]; 
   int adet = listBox1.Items.Count; 
   try 
   
      for (int i = 0; i < adet; i++) 
        takimlar[i] = listBox1.Items[i].ToString(); 
   
   catch 
   
      MessageBox.Show("Dizi Değişkenin sınırı aşıldı\n"
           "Yalnızca ilk 5 eleman diziye aktarıldı"); 
   
 

Koda dikkat edilirse catch deyiminin kullanıldığı satırda catch’den başka bir şey yoktur. Bu catch örneğinden sonra okurun çalışma anında hataya neden olabilecek satırları nasıl catch bloğuna alması gerektiğini kavradığına inanabilirsiniz. Burada da hataya neden olması muhtemel satırlarda okurun yabancısı olmadığı bir tek işleme yer verdim. Ötesi şimdiye kadar try-catch bloklarıyla ilgili olarak yalnızca şunu yazdım:Çalışma anında try bloğundaki herhangi bir satır hataya neden olursa programın işletimi hemen catch bloğuna geçer ve programın çalışması kırılmaz. 

Artık herhangi bir hata meydana geldiğinde programın işletimi try bloğundan catch bloğuna geçtiğinde neler oluyor sorularına cevaplar verebiliriz. Bu düşünce ile yukarıda verdiğim kodu aşağıdaki gibi değiştirdim. 

private void Form1_Click(object sender, EventArgs e) 
 
  string[] takimlar = new string[5]; 
  int adet = listBox1.Items.Count; 
  try 
  
    for (int i = 0; i < adet; i++) 
      takimlar[i] = listBox1.Items[i].ToString(); 
   
  catch(IndexOutOfRangeException Hata) 
 
    MessageBox.Show("Meydana gelen hatanın mesajı:\n"+ Hata.Message); 
  }
}

Bazı okurlar muhtemelen itiraz edip diyeceklerdir ki, böyle adım adım anlatmak, okuru ikna etmeden başka konuya geçmemek sayfa sayısını arttırmaz mı? Elbette sayfa sayısı artar. Hem okuru konuya hazırlayacaksınız, hem kafasında oluşması muhtemel soruları öngörüp tek tek cevap vereceksiniz, hem okur saçını başını yolmadan yazılanları kolayca okuyacak, hem okur yazılanları ikinci kez okumak zorunda kalmasın diyeceksiniz hem de metin kısacık olacak. Tabii bu mümkün değildir. Yani yazar arkadaşımız tercihini yapacak: Ya anlatmak istediği konunun bütün boyutlarını içeren bir örnek verip onun üzerinde birkaç cümle yazıp başka hemen konuya geçecektir ya da anlatmak istediği konuyu alt konulara bölüp her seferinde okura bu alt konulardan birisini anlatacaktır. 

Tam bu noktada
catch(IndexOutOfRangeException Hata) satırı üzerinde biraz durmak ve tek başına catch yazılan satırdan farkını anlatmak gerekir. Kitabımda bu amaçla şu cümleye yer vermiştim: try bloğundaki satırlarda çalışma anında dizi değişkenlerle ilgili bir hata meydana geldiğinde IndexOfRangeException sınıfının örneği hazırlanıp catch bloğuna gönderilir. Demek ki try bloğunda nasıl bir hata meydana gelirse o hatayla ilgili sınıfın örneği alınıp catch bloğuna gönderiliyor. Eğer catch bloğunun ilk satırında catch deyiminden sonra parantezlerin içinde söz konusu sınıf tipinde bir değişken tanımlanmışsa o hata yakalanıyor. Daha doğrusu meydana gelen hatayı temsil eden sınıfın örneği catch deyiminin olduğu satırda tanımlanan değişkene aktarılıyor. Zaten verdiğim kodda bilerek bu nesnenin Message özelliğinin içeriğine baktım. Konunun hemen devamında okurun ilgili sınıfın örneğinin alınıp catch bloğuna gönderilmesi işlemini hemen kavramaması ihtimali yüksek olduğu için daha önce sizlerle paylaştığım Hata Yakalamak ve Exception Sınıfları adlı makaleye aşağıda verdiğim 2 paragrafı ve kısa kodu ekledim. 

try bloğunda meydana gelen hatadan dolayı catch bloğuna gönderilen bütün nesneler System’de bulunan Exception sınıfından türetilen sınıfların örnekleridir. Bu kodda dizi değişkenin olmayan bir elemanı üzerinde işlem yapılmak istendiği için catch bloğuna IndexOutOfRangeException tipinde bir nesne gönderilir. Konu üzerinde düşünmenizi sağlamak için yukarıdaki sayfalanda verdi­ğim örneği aşağıdaki gibi düzenledim. Değişken adı çalma suçumu(!) hafifletmek için DateTime tipindeki değişkene “Tarih” yerine “History” adını verdim


private void textBox1_Leave(object sender, EventArgs e) 
 
   DateTime History; 
   try 
   
     History = Convert.ToDateTime(textBox1.Text); 
   
   catch(IndexOutOfRangeException Hata) 
   
      MessageBox.Show("Girdiğiniz tarih veya saat yanlış"); 
      textBox1.Focus(); 
   
 

Bu şartlarda TextBox’a DateTime tipine dönüştürülemeyecek bilgi girilip TextBox’tan ayrılıp Leave olayı meydana getirildiğinde try bloğundaki satırlar hataya neden olur ve programın işletimi catch bloğunda geçer. Ne var ki catch bloğunda dönüştürme işlemi sonucu meydana gelen hata yakalanamaz. Çünkü catch deyimine ait parantezin içinde IndexOutOfRangeException tipinde değişken tanımlandığı için catch bloğundaki satırlar işletilmeyip meydana gelen hatadan dolayı programın çalışması kırılır. 

Bu açıklamadan sonra artık okura birden fazla catch bloğundan söz edilebilir. Bu düşünce ile birden fazla hataya neden olabilecek basit bir kod hazırladım. Aşağıda verdiğim kodda TextBox1 ve TextBox2’nin içeriğini Convert sınıfının ToByte() metodu ile dönüştürüp Number1 ve Number2 adını verdiğim byte tipindeki değişkenlere aktardım. Tanımladığım bu değişkenker Byte tipinde olduğu için bu TextBox’lara girilen bilgi 255’ten büyük olduğunda OverflowException hatası ile karşılaşılır. Normalde bu değişkenlere alışkanlıklarım gereği Sayi1, Sayi2 gibi adlar verirdim. Değişken adı benzerliği kabahatini tekrar işlememek için “Sayi” yerine Number’ı tercih ettim. 

private void Hesapla_Click(object sender, EventArgs e) 
 
   byte Number1 = Convert.ToByte(textBox1.Text); 
   byte Number2 = Convert.ToByte(textBox2.Text); 
   float Number3 = Number1 / Number; 
   textBox3.Text = Number3.ToString();   
 

Benzer şekilde bu 2 TextBox’a ToByte() metodu ile Byte tipine dönüştürülemeyecek bilgi girilirse FormatException hatası meydana gelir. Tabi kodun devamında Byte tipindeki bu 2 değişkenin içeriği birbirine bölündükleri için sıfıra bölme yani DivideByZeroException hatası meydana gelebilir. Bu kısacak kodda 3 hatanın meydana gelmesi muhtemel olduğu için okura Exception sınıfları hakkında bilgi vermek artık kolaylaşmıştır. Bazı yazarlar benzer bir işlemi, bir metodu veya sınıfı anlatırken örnek verirken özenli davranmazlar. Dolayısıyla verdikleri örnekle ilgili olarak okurun kafasında beliren soruları öngörmeye çalışmazlar. Bu nedenledir ki bazı arkadaşlar yukarıda verdiğim basit kodu küçümserler. Sanki karışık örnek verdiklerinde okurların kendilerine saygısı artacakmış… 

Yukarıdaki sayfalarda amaç try-catch blokları hakkında bilgi vermekti. Tabi bu yapılırken ister istemez birkaç Exception sınıfından söz etmek gerekiyordu. Madem Exception sınıflarının nasıl kullanıldığından söz ettik artık .NET Framework ile hazır olarak gelen ve sık kullanılan bazı Exception sınıflarından söz edebiliriz. Tabi .NET Framework ile birlikte çok sayıda Exception sınıfı hazır olarak geldiği için hepsini anlatmak, hepsinden söz edip örnek vermek mümkün değildir. Ötesi bazı Exception sınıfları ancak ilgili oldukları konu ile paralel anlatıldığı zaman anlaşılmaktadır. Örneğin henüz Thread’ler hakkında bilgi sahibi olmayan okura Thread’lerle ilgili Exception sınıfından söz etmek anlamlı değildir. Gelin InvalidCastException ve
NullReferenceExceptionsınıfından nasıl söz ettiğimi birlikte inceleyelim: 

Tip dönüştürme işlemleri sırasında hata meydana geldiğinde InvalidCastException hatası meydana gelmektedir. InvalidCastException sınıfını anlatmak için aşağıda verdiğim kodu hazırladım. Bu kodda “Nesne” adı verilen object tipindeki değişkenin içeriği rakamlardan meydana geldiği için Unboxing işlemi yapılıp sorunsuz bir şekilde int tipindeki değişkene aktarılır. 

object Nesne = 2008;
try 
 
   int Yil = (int)Nesne; // Tehlikeli bir değişken adı 
   this.Text = Yil.ToString(); 
 }
catch (System.InvalidCastException Hataspor) 
 
   MessageBox.Show("Dönüştürme hatası meydana geldi" + n\r" + Hataspor.Message); 
 

object tipindeki değişkenin içeriği int tipindeki değişkene aktarılırken Unboxing işlemi başarısız olsaydı InvalidCastException hatası ile karşılaşılırdı. Başka bir deyişle object tipindeki değişken int tipindeki değişkene aktarılamayacak bilgi içeriyor olsaydı dönüştürme işlemi başarısız olurdu. 

null yapılmış bir nesnenin özelliklerini kullanmak isterseniz NullReferenceException hatası ile karşılaşılır. Bu hata ile nasıl karşılaşıldığını göstermek için bir Bitmap nesnesi hazırladım. Ardından bu nesneyi null yapıp Width ve Height özelliklerini kullanmayı denedim. Aşağıda verdiğim kodda “i” ve “j” başka yerli yazarlar tarafından daha önce register edilmiş(!) değişken adları oldukları için alışkanlıklarımı bir tarafa bırakıp çift “ii” ve çift “jj” tercih ettim. 

System.Drawing.Bitmap Resim;
openFileDialog1.ShowDialog();
string Dosya = openFileDialog1.FileName;
try 
 
   Resim = new System.Drawing.Bitmap(Dosya); 
   Resim = null; 
   int ii = Resim.Width; 
   int jj = Resim.Height; 
 }
catch(NullReferenceException) 
 
   MessageBox.Show("Nesne null yapılmış"); 
 

Şimdi bazı okurlar diyecekler ki bu 2 sınıfı anlatmak için verdiğin kısacak örneklerde ne var? Gerçekte bu 2 örnekte orijinal bir şey yok. Madem bu kısa örnekler bu 2 sınıfın işlevini göstermek için verildiğinde okur bir sayfalık bu metni okuduğunda
InvalidCastException ve NullReferenceExceptionsınıfları hakkında ilk okumada bilgi sahibi olur mu olmaz mı ona bakmak gerekir. Ötesi bu Exception sınıflarıyla ilgili olarak verilen örneklerde anlaşılmaz bir yan yoktur diyorsanız sorun yoktur.


Finally Bloğunu Nasıl Anlattım 

Yukarıda anlatılan şekilde try-catch bloğunun işleyişi hakkında okuru bilgilendirdikten sonra finally bloğundan kısaca söz ettim. Neden mi finally bloğundan çok sonra söz ettim? Nedeni son derece basit : Okura yabancısı olduğu birden fazla konuyu aynı anda anlatmama kaygısı bu tercihimde etkili oldu. Yoksa bir örnekte try-catch-finally blokları bir seferde anlatılır. Tabi bu durumda henüz yolun başında olan, daha doğrusu hata yakalama ve Exception sınıfları hakkında yeterli bilgisi olmadığı için kitap edinen, makale okuyan okur yazılanları anlamakta zorluk çekecekti, belki yazılanları sonuna kadar okumayacaktı. Finally bloğu hakkında bilgi verirken aşağıdaki gibi basit bir örnek hazırladım. 

private void Resim_sec_Click(object sender, EventArgs e) 
 
   openFileDialog1.ShowDialog(); 
   string kutuk = openFileDialog1.FileName; 
   Bitmap Resim = new System.Drawing.Bitmap(kutuk); 
   pictureBox1.Image = (Bitmap)Resim;
   Resim = null;      
 

Dikkat edilirse bu kısacak kodda ne try-catch ne de finally bloğu var. Niye mi her 3 bloğu bir seferde hazırlayıp vermedim? Amaç konuyu adım adım anlatıp ilk okumada anlaşılmasını sağlamaktır. Ötesi okurun bildiği bir konudan hareketle yeni bir konu anlatılmak istenmektedir. Eğer finally bloğunun işlevini henüz kavramamış okura finally bloğu ile Dispose işleminin yakınlığından söz etmiş olsaydım Dispose() metodu ve Dispose işlemi hakkında yeterince bilgisi olmayanların kafasını karıştırıp finally bloğunu anlatabilme şansını zora sokardım. Ötesi dispose işlemi hakkında ayrıntılı bilgisi olan okur zaten finally bloğunun ne işe yaradığını biliyordur. Bu kodu verdikten sonra kitapta aşağıda verdiğim 2 paragrafa ve koda yer verdim. 

Kullanıcı OpenFileDialog nesnesi sayesinde ekrana getirilen diyalog kutusunu dosya seçmeden kapatır veya uygun olmayan bir dosyayı seçerse hata meydana gelir. Kullanıcının yanlış yaptığı veya yapmadığı dosya seçiminden dolayı meydana gelecek hata konusunda kendisine bilgi vermek için yukarıda verdiğim kodu aşağıdaki gibi düzenledim. 

private void Resim_sec_Click(object sender, EventArgs e) 
 
   System.Drawing.Bitmap Resim; 
   openFileDialog1.ShowDialog(); 
   string kutuk = openFileDialog1.FileName; 
   try 
   
      Resim = new System.Drawing.Bitmap(kutuk); 
      pictureBox1.Image = (Bitmap)Resim; 
      Resim = null;      
   
  catch 
  
     MessageBox.Show("Uygun dosya seçmediniz"); 
  
 

Kullanıcı “Aç” diyalog kutusunda resim dosyası seçmezse veya uygun olmayan bir dosyayı seçerse catch bloğundaki satır işletilip kullanıcıya bilgi verilir. Ancak bu durumda Bitmap tipindeki nesne bellekte yaşamaya devam eder. Çünkü “Resim” adını vermiş olduğum Bitmap nesnesini null yapan satırı try bloğuna yazmıştım.Hata meydana gelsin veya gelmesin mutlaka işletilmesini istediğiniz satırlar varsa bu satırları finally bloğuna yazmalısınız. finally bloğunun nasıl kullanıldığını anlatmak için yukarıda verdiğim kodu aşağıdaki gibi değiştirdim. Burada Bitmap tipindeki değişkeni blok içinde tanımladı­ğım için Garbage Collector zaten bir süre sonra devreye girip bu nesneyi bellekten temizler ama buradaki amacımız deneysel. 

private void Resim_sec_Click(object sender, EventArgs e) 
 
   System.Drawing.Bitmap Resim; 
   openFileDialog1.ShowDialog(); 
   string Dosya = openFileDialog1.FileName;
   try 
   
      Resim = new System.Drawing.Bitmap(Dosya); 
      pictureBox1.Image = (Bitmap)Resim; 
   
  catch 
   
   MessageBox.Show("Uygun dosya seçmediniz"); 
    
  finally 
    
        Resim = null; 
    
   } 

Bu anlatılanlara göre ister hata meydana gelsin ister gelmesin finally bloğuna her şartta işletilmesi istenen satırlar yazılmalıdır. Her ne kadar konuyu adım adım anlatmış ve bazılarına göre uzatmış olsam bile finally bloğu hakkında yazılanları okumak fazla zaman almaz. Okur kısa sürede finally bloğunun işlevi hakkında bilgi sahibi olur. Tabi buradaki asıl amaç finally bloğunun ne zaman ve nasıl işletildiğini anlatmaktır. Yoksa finally bloğunda yapılabilinecek işlemleri tek tek saymak değildir.

Bu yazıya henüz yorum yapılmamış. | 09.10.2009 11:40:41

Programcılar İçin Yazarlık Dersleri - 2 (*)


Film yönetmenleri kendilerine gelen hikayeyi veya senaryoyu nasıl anlatacaklarına, hangi noktalara vurgu yapacaklarına, olayları nasıl sıralayacaklarına karar vermeden önce uzun çalışmalar yaparlar. Ne var ki benzer çalışmayı programcılık üzerine yazanlar yapmıyorlar. Bildikleri konuları bir baştan başlıyorlar anlatmaya. Tabi neyi nasıl anlatmak gerek sorusu üzerinde yeterinde kafa yormamış yazarların konuları anlatış şeklinin ve sırasının akıbeti çoğunlukla şans eseri kabul edilebilir olgunlukta oluyor. Bir önceki makaleyi okunabilir boyutta tutmak için 10. sayfada kesmiştim. 

Yazar Okurun İhtiyaç Duyduğu Tekniklere Mi Odaklanmalı? 

Konu programcılık veya bir programlama dili üzerine yazmak olduğunda yazar temelde 2 kaygından etkilenir. Birinci kaygı; okurun muhtemel ihtiyaçlarını gözetip bilgi vermek ve çok kullanılan tekniklerden söz etmektir. Örneğin ADO.NET konulu bir kitap yazıyorsanız veya bir eğitim merkezinde hocalık yapıyorsanız okurların ve öğrencilerin hazırladıkları SQL Server veritabanını başka bilgisayara götürme ihtiyaçlarını öngörüp ona göre okuru ya da öğrencileri bilgilendirmeyi hedeflersiniz. Tabii okurların veya öğrencilerin konu programcılık olduğunda ileri ki günlerdeki muhtemel ihtiyaçlarının hepsini baştan öngörüp kitabın içeriğini oluşturmak mümkün olmadığına göre yazar kendince bazı seçimler yapar. 

Yazarın veya hocanın programcılık anlatırken etkisinde kaldığı ikinci kaygı ise bazı kavramları veya işlemleri anlaşılabilir yapmak, okurun bu kavramları anlayabilmesidir. Eğer birincil amacınız programcılıkla ilgili bir kavramı, bir işlemi okurun veya öğrencinin anlaması ise, konuyu işlerken veya örnek verirken pratik değer aramaz, vereceğiniz örneğe okurun ileriki günlerde ihtiyacı olur mu olmaz mı bakmazsınız. Örneğin .NET uyumlu programlama dillerinde Application sınıfı ile hiç ilgilenmeden profesyonel kalitede programlar yazmak mümkündür. Bu nedenledir ki birçok yerli yabancı kaynakta ya Application sınıfından hiç söz edilmez ya da birkaç cümle ile geçiştirilir. Tabii Application sınıfının sık gerek duyulan bir kaç metodundan söz edilir ama bu söz etmede Application sınıfına vurgu yapılmaz. Örneğin uygulamanın çalışması sona erdirilirken gerek duyulan Exit() metodundan bir cümle ile söz edilir. Okurunuzu Application sınıfı hakkında mutlaka bilgilendirmek istiyorsanız belki de okurların hiçbir zaman kullanmaya gerek duymayacakları bazı işlemlerden söz edeceksiniz. Örneğin sanki Application sınıfı .NET Framework ile gelmiyormuş gibi davranıp, başka bir deyişle C++ programcıları gibi mesaj kuyruğu hazırlamak isteyebilirsiniz. 

Gelelim bu derslerde sık sık atıfta bulunduğum C# 3.0 kitabıma: Bu kitapta zaman zaman anlattığım konunun kolay kavranmasını sağlamak için yaptığım veya anlattığım işlemlerin pratik değeri var mı yok mu göz ardı ettim. Örneğin Application sınıfı hakkında bilgi verilen bölümde birincil amaç Application sınıfı hakkında yazılanların anlaşılmasını sağlamak olduğundan zaman zaman pratik değeri olmayan işlemler yapılıp üzerinde konuşuldu. Örneğin .NET uygulamalarında Application sınıfının Run() metodu çok özel durumlar hariç yalnızca bir kez kullanılır. Run() metodunun işlevinin kavranması için henüz Application sonlanmamış iken Run() metodunu ikinci kez kullanılıp hata meydana gelmesine neden olup okurun konu üzerinde düşünmesi sağladım. Bu bağlamda yazarlara önerim şudur: Anlattığınız konu kolay anlaşılan ve arka planını bilmek gerekmeyen bir konu ise mümkünse verilen örneklerde pratik değer aranmalıdır. Anlatılan konu zor anlaşılan bir konu ise pratik değer kaygısı başlangıçta bir tarafa bırakılabilinir. 

Ekran Görüntüleri Hangi Büyüklükte Olmalıdır? 

1992 yılında dergilerde yayınlanan ilk yazılarımda ve 1994 yılında yayınlanan ilk kitabımda o günlerin kitaplarından farklı olarak ekran görüntülerine yer vermiştim. Memik Yanık’a hücum etmek isteyenlerin ilk enstrümanı şuydu:“Memik Yanık’ın kitaplarında ekran görüntülerinden başka bir şey yoktur”. Şimdilerde bakıyorum da bırakınız ekran görüntüsüz programcılık kitabı bulmayı makale bulmak bile zordur. Asıl sorun da tam burada başlıyor:Kitap metni içinde veya makalede ne sıklıkta ekran görüntüsü kullanılmalı, ekran görüntüleri hangi büyüklükteki olmalı, ekran görüntüsü sayfanın neresine konulmalıdır, okurun ekran görüntüsünü yazının parçasıymış gibi görmesi için neler yapılmalıdır? Bu gibi sorulardan “bi haber” olanların kitaplarında veya makalelerinde ekran görüntülerini işlevsel kullanabilmeleri şansa veya tesadüfe kalmıştır. İncelediğim birçok yerli ve yabancı kaynakta yazar ekran görüntülerini alıp kitaba konulmasını sağlamış. Ekran görüntüsünü alırken öyle özensiz davranıyorlar ki dikkatli incelerseniz şaşırırsınız. Örneğin yazarın birisi kitabında Visual Studio’nun ilk karşılaşılan penceresini okuruna göstermek için şöyle bir ekran görüntüsünü alıp kitabında kullanıyor.



Tabi bu ekran görüntüsünün orijinal genişliği çok fazla olduğu için ancak %50-60 oranında küçültüldüğü zaman kitaba sığabiliyor. Bu durumda ekran görüntüsünün üzerindeki yazıları ve pencere başlıklarını çıplak gözle okuyabilmek mümkün olamıyor. Memik Yanık tarafından kaleme alınan kitaplarda ise bu ekran görüntüsü aşağıdaki gibi olmaktadır. Tabi bu ekran görüntüsü kitapta fazla yer kaplamasın diye belli bir oradan küçültülüp öyle kullanılırdı.



Gerçekte yazdığım kitaplarda bu tip ekran görüntüleri daha küçüktür. Sanırım ne demek istediğim anlaşıldı. Ekran görüntüleriyle ilgili olarak yapılan bir başka yanlış ise şudur. Yazarımızın(yerli veya yabancı) MessageBox sınıfının Show() metodundan söz ettiğini varsayalım. Yazarımız kitabında muhtemelen aşağıdaki gibi bir ekran görüntüsü kullanır.



Dikkat edilirse bu ekran görüntüsü çok büyük değildir ve kitapta fazla yer kaplamaz. Birçoklarınıza bu normal gelir. Hal bu ki yukarıda verilen ekran görüntüsü %50-60 küçültülürken bu ekran görüntüsü olduğu gibi bırakılmış ve orijinal büyüklüğüyle kullanılmıştır. Yani ne büyütülmüş ne de küçültülmüştür. Bu ekran görüntüsü Memik Yanık tarafından yazılan bir kitapta kullanılsaydı aşağıdaki gibi olurdu. Çünkü Memik Yanık kitaplarında kullandığı bütün ekran görüntülerini %30 ile 35 arasında değişen oranlarda küçültüp öyle kullanmaktadır. Çünkü Memik Yanık için en önemli parametre ekran görüntülerinin üzerindeki yazıların çıplak gözle ve gözlerinde bozukluk olmayanlar tarafından kolaylıkla okunabilmesidir.



Belki en doğrusu ekran görüntülerinin boyutları hakkında bilgi verirken yerli yabancı birkaç kitapta kullanılan ekran görüntülerini buraya alıp üzerinde konuşmak olurdu. Ancak bu tercih Memik Yanık’ın suçlanmasına neden olurdu:Yazarlık dersi adı altında başka yazarların eksikliklerini bize anlatıyorsun derlerdi. Tam bu noktada bir yıl önce karşılaştığım trajik komik durumu size anlatacağım. Programcılık konulu bir forumda üyenin birisi bir programcılık kitabı hakkında bilgi istiyordu. Başka bir deyişle ilgilendiği kitabı satın almadan önce forumun diğer üyelerinin görüşlerini almak istemişti. Konu dallanıp budaklanınca “söz konusu kitap elime geçince ciddi bir incelemeden geçirip fikirlerimi sizlerle paylaşırım” demiştim. Aradan henüz yarım saat geçmemişken bir mail aldım: Maili gönderen söz konusu kitabı yayınlayan firmanın avukatıydı. Kitap hakkında konuşursam beni dava edeceklerini beyan ediyordu. Yani henüz görmediğim, içeriğinden haberdar olmadığım bir kitabın tanımadığım yazarı kitabı hakkında ileri ki günlerde bir şeyler yazmamı istemiyordu avukat bey. İşin garip tarafı bu mail bana ulaştıktan sonra birkaç ay sonra kitabı inceleme imkanım oldu. Baktım yazar konuya hakim ama bazı anlatım ve konuları sıralama sorunları var. Eğer o kitap hakkında yazsaydım adım gibi eminim ki yazar kitabının ikinci baskısında büyük değişikliklere giderdi. 

Şimdi ise 2. bir olayı anlatacağım. Bir gün bir yayınevinde oturuyordum. İçeriye kendisini tanımayıp ancak C üzerinde yazdığı kitaptan dolayı adını bildiğim bir yazar geldi. Tanışma faslından hemen sonra yazar arkadaş gitti kitabının örneğini alıp geldi. Çünkü yakın bir zamanda kitabının yeni basımını hazırlamak istiyordu. Kitabında yapacağı ekleme veya çıkarmalar konusunda fikirlerimi almak istiyordu. Yarım saat içinde kitabının bazı sayfalarını inceledim kendisine önerilerde bulundum. Oldukça tecrübeli yazarımız bu önerileri tek tek not alıp gitti. Yarım saat içinde kitapta görebildiğim eksikleri, aksaklıkları saymıştım. Çünkü yazar arkadaşın amacı kitabını daha iyi yapmaktı, amacı övgü duymak değildi. 

Ekran Görüntüleri Nasıl Kullanılmalıdır? 

Kitap metni içinde kullanılan ekran görüntülerinin büyüklüklerinden biraz söz ettikten sonra şimdi sırada ekran görüntülerini kullanma sıklığı ve işlevinin üzerinde biraz durmak gerekecek. 1995 yılında DOS ve Windows 3.1 ağırlıklı Herkes İçin Bilgisayar kitabımı yayınladığım günlerde bilgisayar ve programcılık kitaplarında ekran görüntüsü kullanımı pek yaygın değildi. Çünkü DOS ortamında ekran görüntüsü almak zahmetliydi. O zamanlarda kitaplarda ekran görüntülerine yer vermeme kimse bir şey dememişti. Bırakın itiraz edilmesini bu kitaplar okurlardan yoğun ilgi görmüştü. Ne zaman ki kitaplarımın sayısı fazlalaştı saldırılar başladı. Bazıları çeviri yaptığımı söylerken bazıları “kitaplarında ekran görüntüsünden başka bir şey yok” diyorlardı. Tabii bunları söyleyenler genelde Memik Yanık kitabı okumamış ve Memik Yanık kitaplarına ihtiyaç duymayan kişilerdi. Memik Yanık’a kızıyorlardı, programcılık gibi teknik bir konunun bu kadar kolay öğrenilebilir olması insanları şaşırtıyordu. Neden Memik Yanık kitapları diğer yazarların kitaplarından daha kolay okunuyor, kolay anlaşılıyordu? Bu sorunun en kestirme cevabı; okuru ikna etmeye çalışırken karışık cümlelerden kaçınmak, yer yer ekran görüntülerini kullanmak, küçük tekrarlar yapmaktır. 

Şimdi gelelim asıl konumuza. Yani ekran görüntüleri nerede nasıl kullanılmalıdır sorusuna cevap arayalım.
Konumuz Delphi'de kod yazarak nesneleri ilk yerleştirildikleri formdan başka bir forma taşımak olsun. Amacınız okurun hayal gücünü geliştirmek değilse yapmak istediğiniz işlemi veya amacımızı bir iki cümle ile ortaya koyduktan sonra 2 forma sahip bir Delphi projesi hazırlarsınız. Tabii kitabınızı şişirmeme gibi bir kaygınız varsa veya ekran görüntüleri konusunda özenli davranmayı ilke edinmişseniz kitap metni içinde ekran görüntüsü olarak kullanacağınız formların boyutlarına dikkat edersiniz. 

Bazıları çıkıp diyecekler ki yukarıda bold yapılan cümle yeterince açık değil mi? Okurunuz tıpkı üniversite seçme sınavındaki gibi konuya odaklanmışsa bu cümlenin yeterince açık ve anlaşılır olduğu söylenebilir. Daha doğrusu kolay okunma diye bir kaygınız yoksa veya hemen anlaşılma, hızlı okunma amaçlarınız yoksa yukarıdaki cümleden sonra formdan forma nesne taşıyan Delphi kodunu verirsininiz olur biter. Bu durumda yazılanların programlama dilinin help metinlerinden bir farkı olmaz. Aşağıda verilen metni kendi cümlelerimle yazmış olmakla birlikte kaleme alırken başka yazarları taklit etmeye çalıştım. Konunun devamında ekran görüntülerini kullanıp kendi tarzımda anlatacağım. 

Tam noktada Delphi ile ilgisi olmayan yazarlar ve yazar adayları için 2 cümle yazmam gerekiyor: Aşağıda hiç ilgilenmediğiniz, belki de bundan sonra hiç ilgilenmeyeceğiniz bir programla dili hakkında son derece teknik bir işlem hakkında bilgi verilmektedir. Bazı arkadaşlar tam bu noktada Delphi ile ilgili sayfaları atlayacaklardır. Nasıl ki lisede verilen matematik derslerinde ikide bir söylenip “türevin integralin gerçek hayatta bana ne faydası olacak, hangi işlemi yaparken kullanacağım?” diye fikirlerini beyan edenler bilim üretebilme becerisine sahip kişiler değillerse Delphi konulu bu metni okuma zahmetine katlanamayacak olanların iyi yazar olabilmeleri şüphelidir. Yazar olmak istiyorsanız, yazdıklarınız anlaşılsın istiyorsanız öncelikle yabancısı olduğun konuları okuyabilme sabrını göstermeniz gerekir. Üzerinde konuşacağım örnek metni italik yaptım. 

Delphi'de bir formdaki nesneleri veya kontrolleri başka bir forma taşırken RemoveComponent ve InsertComponent metotları kullanılmaktadır. Form1'deki Edit1 ve Edit2’nin Parent özelliklerinde değişiklik yapılırsa Form2’nin üzerinde görüntülenirler. 

procedure TForm1.AktarClick(Sender: TObject);
begin 
  Edit1.Parent := Form2; 
  Edit2.Parent := Form2;
end; 

Şimdi ise Form2’de görüntülenen bu 2 nesnenin For1’den silinmesini sağlayacağım. 

procedure TForm1.SilClick(Sender: TObject);
begin 
  Form1.Components[1].Free; 
  Form1.Components[0].Free;
end; 

Bu 2 satır sayesinde Form1’deki ilk 2 kontrol silinir. Koda dikkat ederseniz Edit1 ve Edit2 nesneleri Form2’nin üzerinde görünürken bu kontroller henüz Form1’e aittir veya Edit1 ile Edit2’nin sahibi Form1’dir. Bu nedenle Free metodu ile silme işlemini yaparken Form2 yerine Form1’ın adını yazdım. Şimdi RemoveComponent ve InsertComponent metotlarını bir yordama alıp öyle işleteceğim. 

procedure TForm1.Uzaklastir(Bilesen: TComponent; Sahip: TComponent);
begin 
  Bilesen.Owner.RemoveComponent(Bilesen); 
  Sahip.InsertComponent(Bilesen);
end; 

“Uzaklastir” adını verdiğim yordamı bu şekilde hazırladıktan sonra aşağıdaki gibi hazırlık yaptım. Bu kod sayesinde Form1’deki 2 Edit Form2’ye aktarılır.
 

procedure TForm1.AktarClick(Sender: TObject);
begin 
  Form1.Edit1.Parent := Form2; 
  Form1.Edit2.Parent := Form2; 
  Uzaklastir(Edit1, Form2); 
  Uzaklastir(Edit2, Form2);
end; 

Aslında bu metin Delphi konusunda ortalama bilgiye sahip olanlar için son derece anlaşılırdır. Ne var ki Delphi uzmanları dönüp bu metne bakmazlar bile. Onların burada yazılanları anlamaları için metindeki kod satırlarına uzaktan bir kaç saniye bakmaları yeterlidir. Biz yazarlar uzmanlar için kitap yazmadığımız için, başka bir deyişle yazdıklarımızla hiç ilgilenmeyecekleri baştan belli olanları gözeterek konuları kaleme almadığımız için uzmanların böyle bir metin karşısındaki yaklaşımlarını ölçü almayız. Hemen söyleyeyim ki yukarıda verilen kısacak metin ve birkaç satırlık kod Delphi'nin bileşen kavramının temelini oluşturuyor. Bu nedenle oldukça önemlidir. Önemli olduğu için de okurun yazılanları kavraması için ek açıklamalar yapılmalıdır. Üstelik bu ek açıklamalar pat diye yapılmamalıdır. Okur öncelikle olası sorunlarla yüz yüze getirilmelidir. Okur formlar arası nesne taşıma konusunda karşılaşacağı sorunlar hakkında bilgi sahibi yapıldıktan sonra çözümden söz edilmelidir. 

Bu metni okuyan kişi Delphi uzmanı değilse(ki Delphi uzmanı zaten böyle bir metne dönüp bakmaz) yapılan işlemlerin geri planını merak eder. Belki de işin içinden çıkamaz. Bu konu bu şekilde anlatıldığı zaman anlaşılmama olasılığına karşı, başka bir deyişle anlaşılmayı garanti etmek için bu konuyu aşağıdaki gibi anlatmayı tercih ettim. Bu şekilde düzenlenen metni hızlıca bir kez okursunuz. İkna olup zaman kaybetmeden konuyu kavramış halde başka konuya geçersiniz. 

Delphi hakkında ortalamanın üzerinde bilgisi olan birisi bu metni gördüğünde büyük bir ihtimalle “yazar kitabı şişirmiş, sayfaları ekran görüntüleri ile doldurmuş” diyecektir. Programcılığı meslek olarak seçmiş olanların ve programcılık üzerine yazanların gözden kaçırdıkları önemli bir nokta var: Programcılar hayal güçleri olağanüstü kişiler değildir. Bu nedenle zaman zaman ekran görüntülerine yer verip konudan kopmalarının önüne geçmek gerekir. 

Nesneleri Bir Formdan Diğerine Taşımak 

Delphi projelerinde bir formdaki kontrolleri başka bir forma taşırken RemoveComponent ve InsertComponent metotları kullanılmaktadır. Bu 2 metodun nasıl kullanıldığını anlatmak için 2 forma sahip bir proje hazırladım.

 

Bu ekran görüntüsü kitap veya makale metni içinde yaklaşık 5 satırlık yer kaplamaktadır. Başka bir deyişle kitapta bu büyüklükte bir ekran görüntüsüne yer verildiği zaman kitap metni 5 satırlık bir paragraf kadar artmış olur. Yazarın bu ekran görüntüsünü 2 satırda tarif edeceğini düşünürsek kitapta bu ekran görüntüsüne yer verilmekle gerçekte kitap metni 3 satır kadar artmış oluyor. Çünkü yukarıda verdiğim metne bakarsanız “2 forma sahip proje hazırladım” demekle yetindim. Eğer ekran görüntüsüne yer vermeseydim okurun hayal gücüne yaslanıp ekran görüntüsü verilen 2 formu uzun uzun tarif etmem gerekecekti. Tabi bazı yazarlar özensiz davranıp sanki artı bir faydası olacakmış gibi ekran görüntülerini kocaman alıyorlar sonra da küçültüyorlar. Bu durumda ekran görüntüsündeki yazıları okumak için büyütece gerek duyuluyor. 

Çalışma anında ilk formdaki “Göster” düğmesi tıklandığında “Form2” ekrana getirilecek. Bu amaçla Unit2’yi Uses bloğunda Unit1’e dahil ettikten sonra “Goster” düğmesi için aşağıda verdiğim kodu yazdım.
 

procedure TForm1.GosterClick(Sender: TObject);
begin 
   Form2.Show;
end; 

Çalışma anında “Aktar” düğmesi tıklandığında ise Edit1 ve Edit2’nin Parent özelliklerinde değişiklik yapılıp Form2’nin üzerinde görüntülenmesini sağlayacağım. 

procedure TForm1.AktarClick(Sender: TObject);
begin 
  Edit1.Parent := Form2; 
  Edit2.Parent := Form2;
end; 

Aşağıda verilen ekran görüntüsünü önce “Göster”, sonra “Aktar” düğmelerini tıkladıktan sonra aldım. Bu sırada Edit1 ve Edit2 projedeki 2. formun üzerinde görünüyor olsalar bile bu 2 nesnenin sahibi henüz Form1’dir.




Gerçekte tam bu noktada Delphi programcıları için önemli bir konu var: Edit nesneleri Form2’nin üzerinde görünürken sahibi henüz Form1’dir. Bu ekran görüntüsü sayesinde okurun bu önemli noktaya dikkati çekilmektedir. Bu ekran görüntüsü kullanılmasaydı okur belki aynı metni 2 kez okumak zorunda kalacaktı. 

Çalışma anında “Sil” düğmesi tıklandığında Form2’de görüntülenen ilk 2 nesnenin Form1’den silinmesini sağlayacağım. Bu amaçla ilk formdaki “Sil” düğmesinin Click olayıyla ilgili metodu aşağıdaki gibi düzenledim.
 

procedure TForm1.SilClick(Sender: TObject);
begin 
  Form1.Components[1].Free; 
  Form1.Components[0].Free;
end;

“Sil” düğmesinin Click olayını temsil eden metoda yazılan bu 2 satır sayesinde Form1’deki ilk 2 kontrol silinir. Koda dikkat ederseniz Edit1 ve Edit2 nesneleri Form2’nin üzerinde görünürken bu kontroller henüz Form1’e aittir veya Edit1 ile Edit2’nin sahibi Form1’dir. Bu nedenle Free metodu ile silme işlemini yaparken Form2 yerine Form1’ın adını yazdım. Burada yapılması gereken Parent özelliği ile nesnenin görüntülenmesinden sorumlu olacak formu(yani sınıfı) değiştirdikten sonra Owner özelliğini de değiştirmektir. Bu işlemi yapmak için aşağıda verdiğim kodu yazdım.
 

procedure TForm1.AktarClick(Sender: TObject);
begin 
  Form1.Edit1.Parent := Form2; 
  Form1.Edit1.Owner.RemoveComponent(Edit1); 
  Form2.InsertComponent(Edit1); 
  Form1.Edit2.Parent := Form2; 
  Form1.Edit2.Owner.RemoveComponent(Edit2); 
  Form2.InsertComponent(Edit2);
end; 

Bu kod hakkında bilgi vermeden bu kodun hataya neden olacağını söylemeliyim. Bu kodda önce Form1’deki “Edit1” nesnesi RemoveComponent metodu ile Form1’den uzaklaştırılıp InsertComponent metodu ile Form2’ye eklenmektedir. Ancak Edit’ler ve diğer nesneler RemoveComponent metodu ile Form1’den uzaklaştırıldığı anda bellekten silinmiş olmaktadır. Dolayısıyla olmayan bir nesneyi InsertComponent metoduna parametre olarak vermek hataya neden olur.
 

Bu sorunu gidermek için ilk akla gelen yöntem bu işlemi yapacak bir procedure hazırlamaktadır. Daha önce Türkiye’de yayınlanan bir kitapta bu yöntem anlatıldığı için öncelikle söz konusu Edit nesnesini RemoveComponent metodu ile Form1’den uzaklaştırmadan önce bir değişkene aktamayı tercih ettim. 

procedure TForm1.AktarClick(Sender: TObject);
Var 
   E :TEdit;
begin 
   Form1.Edit1.Parent := Form2; 
   E := Form1.Edit1; 
   Form1.Edit1.Owner.RemoveComponent(Edit1); 
   Form2.InsertComponent(E); 
   Form1.Edit2.Parent := Form2; 
   E := Form1.Edit2;    
   Form1.Edit2.Owner.RemoveComponent(Edit2); 
   Form2.InsertComponent(E);
end; 

Bu kod sayesinde Edit1 ve Edit2’nin Form1 sınıfıyla bir ilişkisi kalmaz. Bu kod işletildikten sonra Edit1 ile Edit2’nin hem Owner’ı hem de Parent’ı Form2 olur. Bu şartlarda, yani Form2’de yalnızca 2 nesne varken “Sil” düğmesi için yazılan kodda önce Edit2 silinmelidir yoksa hata meydana gelir.
 

procedure TForm1.SilClick(Sender: TObject);
begin 
  Form2.Components[1].Free; 
  Form2.Components[0].Free;
end; 

Şimdi ise RemoveComponent ve InsertComponent metotlarını bir metoda alıp öyle işlete­ceğim. Hazırlayacağım metot TComponent tipinde 2 parametreye sahip olacaktır.
 

procedure TForm1.Uzaklastir(Bilesen:TComponent;Sahip:TComponent);
begin 
  Bilesen.Owner.RemoveComponent(Bilesen); 
  Sahip.InsertComponent(Bilesen);
end; 

“Uzaklastir” adını verdiğim metodu bu şekilde hazırladıktan sonra “Aktar” düğmesinin Click olayını temsil eden metodu aşağıdaki gibi düzenledim. Bu kod sayesinde Form1’deki 2 Edit nesnesi Form2’ye aktarılır.
 

procedure TForm1.AktarClick(Sender: TObject);
begin 
  Form1.Edit1.Parent := Form2; 
  Form1.Edit2.Parent := Form2; 
  Uzaklastir(Edit1, Form2); 
  Uzaklastir(Edit2, Form2);
end; 

Birinci anlatım daha kısa oldu. Delphi konusunda belli bir düzeye gelmiş kişilere, daha doğrusu artık kitap almayıp, Memik Yanık veya başka bir yazar tarafından kaleme alınmış metinlere dönüp bakmayanlara göre kısa olanı tercih etmek gerekir. Nasıl olsa onların bu konuyu öğrenme gibi bir dertleri yoktur. Yazar arkadaşım fazladan yazılan her kelime her cümle okur için zaman kaybıdır, kitabınızdan alınacak faydanın azalmasıdır. Ne var ki vur deyince öldürmemek gerekir, metin kısa olacak diye okunması zor, okunsa bile söylenenler anlamak zahmetli oluyorsa durup düşünüp metni yeniden kaleme almak gerekir. 

Kod İçinde Açıklama Metni Kullanmak 

Bazı yerli ve yabancı yazarlar makalelerinde ve kitaplarında kullandıkları 15-20 satırlık yani yarım sayfalık kodun içine uzun uzun açıklamalar yerleştirerek söz konusu kodun 1,5-2 sayfa kadar uzamasını tercih ediyorlar. Kodun arasına uzun açıklamalar ekleyerek kolay anlaşılmak veya kodda kullanılan her satırın işlevinin okur tarafından hemen fark edilmesini istiyorlar. İlk bakışta sanki doğru bir terciymiş gibi görülür bu. Böyle bir tercih ile hazırlanan metni okumak bir bakıma dublajı bilmediğiniz bir dilde yapılmış olup bol konuşmalı alt yazılı bir filmi izlemeye benzer. Hele hele filmdeki karakterler hızlı konuşuyorlarsa bazen de aynı anda birden fazla kişi konuşuyorlarsa bütün alt yazıları okuyup filmi anlamak ağır bir işte çalışmak gibi yorucudur. Yani yazarlarımız kodun içine bol bol açıklama metni koyarken sanıyorlar ki okur konuyu daha kolay anlıyor, kodda yapılan işlemleri bir bakışta kavrıyor. 

Y
ıllardır yüz binlerce programcılık konulu sayfa okumuş birisi olarak söylemek isterim ki kodun içinde uzun açıklamalar yapmak kadar metni zor okunur yapan başka bir teknik yoktur. Elbette kodun içine açıklama metni yazılır, elbette dozunda tutulmuş açıklama metninin okura katkısı olur. Burada dikkat edilmesi gereken açıklama metinlerin kısa olması ve sayılarının fazla olmamasıdır. 

Yazarın birisi daha önce hakkında hiç söz etmediği bir kavram veya anahtar kelime hakkında kodun içinde 3 satırlık yani neredeyse bir paragraflık açıklama metnine yer veriyor. Devamında bir sonraki kod satırı için tekrar açıklama metni kullanıyor. Başka bir deyişle kod satırları, kod satırlarını açıklayan metinlerin içinde kayboluyor. 

Açıkçası hazırladığınız 10 satırlık kodun 5-6 satırı için kod içinde açıklama metni hazırlıyorsanız okurunuzu o kod için hazırlamamışsınız, okurunuz o kodda kullanılan sınıflardan, metotlardan ve anahtar kelimelerden henüz habersizdir demektir. Yapılması gereken; kodda kullanılan sınıflar, anahtar kelimeler hakkında önceden okura bilgi verip ondan sonra kod hazırlamaktır. Kod içinde kullanılmasına rağmen daha önce söz edilmeyin veya okurun unutmuş olabilme ihtimali yüksek bir iki metot hakkında en fazla 3-4 kelimelik açıklama metinleri yararlı olabilir.

*Bu metni yaklaşık 1 yıl önce yazıpilk kez memikyanik.com'da yayınlamıştım. Bütün teknik makaleleri memikyanik.net'e almak istediğim için gözden geçirip birkaç yazım hatasını düzeltip buraya aldım. Bu sayede daha önce memikyanik.com'da rastlamayanların istifadesine sunmuş olduk.

Bu yazıya henüz yorum yapılmamış. | 08.10.2009 00:30:22

En İyi Buluş Sonradan Tekrar Yapılan Buluştur


Yıllar önce öğrenciyken yani Fortran IV zamanında hocamız sıralama işlemleri üzerinde durmuştu. Yani günümüzde sıkça kullanılan sıralama algoritmaları bundan 25 yıl önce bile biliniyordu kullanılıyordu. Kısa sürede mesleğinin zirvesine çıkmış yerli bir yazar sıralama algoritmalarını yeniden keşfedip programcılık dünyasına sundu. Bunu yaparken yani yeniden keşfettiği sıralama algoritmalarının kullanımını serbest bıraktı ama programcılık kitabı yazarlarının kitaplarında bu algoritmalardan söz etmelerini yasakladı. Yani anlayacağınız bu yazarımız yeniden keşfettiği bu algoritmalar konusunda insaflı davrandı. Şimdi gelin 2003 yılı içinde keşfedilen bu algoritmalardan Selection Sort adlı olanı 2004 yılında yayınlanan kitabında Memik Yanık nasıl anlatmış bakalım. 

Gerçekte 2004 yılında yayınlanan C# kitabımda Sıralama Algoritmaları diye bir konu yoktur. Öyle bir konu olsaydı en az 5-6 sıralama algoritmasını arka arkaya anlatır değişik bilgileri sıralarken bu algoritmaları kullanırdım. Kitabımda iç-içe for döngülerine örnek olması için Selection Sort algoritmasını kullandım. Çünkü Seçmeli Sıralama diye Türkçeleştirilen Selection Sort algoritmasının özünde iç-içe 2 for döngüsü vardır. Neyse bunun üzerinde fazla durmaya gerek yoktur. Madem kitabımda Selection Sort’un adını bile etmeden kullandığıma göre bu algoritma üzerinde biraz konuşalım. 

İşe bir soruyla başlayalım: Selection Sort algoritması ile ne yapılır? Cevap: istenen bilgiler bir özelliğe göre sıralanır. Yani anlayacağınız bu algoritmadan yararlanmak için elimizde sıralanacak üç beş bilginin olması gerekiyor. Bu algoritmayı geçtiğimiz yıllarda Pascal, Quick Basic, C veya C++ için yazanlar genellikle 2 dizi değişken tanımlayıp sıralayacakları bilgileri ilk dizi değişkene aktarırlardı. Sonra ilk dizi değişkenin içeriğini sıralayıp ikincisine aktarırlardı. En son olarak bilgilerin sıralanmış halini ekrana yani DOS penceresinde yazarlardı. Madem iç-içe for döngülerini pardon Selection Sort algoritmasını C# programlama dilini anlatmak kaygısıyla yazdığım kitapta kullanacağım sıralayacağım bilgileri sizce nereye aktarmam caizdir? 

İşte ilk aklıma gelenler: Bir ArrayList nesnesi hazırlanıp sıralanacak bilgiler bu ArrayList’e aktarılır. Tabi bazılarınız hemen itiraz edip ‘sıralayacağın bilgileri ArrayList’e aktarmak yerine formun üzerinde bize göstereceğin bir kontrol yok mudur?’ sorusunu yönelteceklerdir. Aslında .NET Framework ile gelen kontrollerin içinde bu amaçla kullanılabilinecek kontroller vardır. Örneğin forma bir TextBox yerleştirilip bu TextBox’ın MultiLine özelliği True yapılıp sıralanacak bilgiler bu TextBox’a aktarılabilir. Bilgilerin sıralanmış hali ise başka bir TextBox’a aktarılır. Aşağıda verdiğim ekran görüntüsünde kullanımı yasak olan nesneler yoktur. Bu formun üzerindekiler MultiLine özellikleri True yapılmış 2 TextBox var.



Bu şekilde MultiLine özelliği True yapılmış TextBox’lardan ilkine istenen bilgi aşağıdaki gibi kod yazılarak aktarılabilir. Benzer kod bilgiler sıralandıktan sonra yazılarak bilgilerin sıralanmış hali ikinci TextBox’a aktarılır.

private
void Form1_Load(object sender, EventArgs e)
 {
   textBox1.Text = "Fenerbahçe" + "\r\n" + "Galatasaray" + "\r\n"+ "Beşiktaş";
  }

Gördüğünüz gibi MultiLine özelliği True olan TextBox’lara bu şekilde bilgi aktarmak biraz zahmetlidir. Bu nedenle bu amaçla kullanılabilinecek başka kontrolleri aramak gerekir. TextBox’tan aklıma gelen bir diğer kontrol RichTextBox’tır. RichTextBox’ı kullanmayı ilk akıl edenler yerli bir programcı kitabı yazarı olmadığı için gönül rahatlığıyla kullanılabilir. Ancak ne yazık ki 2004 yılında yayınlanan C# kitabımda bu işlem için RichTextBox yerine boş bulunup ListBox kullanmayı tercih etmişim.Çünkü programcılık kitaplarında bu ve benzeri amaçlar için ListBox kullanmak suç teşkil etmektedir. Çünkü forma ListBox yerleştirip kullanmayı ilk akıl eden mesleğinin zirvesinde olan yerli bir programcılık kitabı yazarıdır. Alın size Selection Sort algoritması yani iç-içe for döngüleri hakkında bilgi vermek için hazırladığım formun şekli.



Gördüğünüz gibi bu form başka kitaplardan esinlenmeden tasarlanacak gibi değildir. Çünkü eldeki beş on bilgiyi kullanıcıya formun üzerinde göstermek ListBox kullanmak öyle herkesin aklına gelebilecek bir şey değildir. Yani Memik Yanık C# kitabını yazarken sıralamak istediği bilgileri formun üzerinde nasıl gösteririm diye günlerce düşünmüş ama aklına bir çözüm gelmemiştir. Sonra mesleğinin zirvesindeki bir yazarın kitabından esinlenip bu işlem için ListBox’ların kullanılabileceği gerçeğini fark etmiştir. Her ne kadar Memik Yanık 15 yıl önce yayınlanan programcılık kitaplarında forma ListBox yerleştirmeyi akıl etmiş olsa bile 2004 yılı şartlarına göre forma ListBox yerleştirme fikri yerli bir yazar tarafından register edilmiştir. 

Memik Yanık kitabı için hazırladığı örnekte forma 2 ListBox yerleştirerek aynı suçu ikinci kez işlemiştir.  ListBox kullanma suçunu 2 kez işlemin ötesinde forma yerleştirdiği Button nesnesinin Name özelliğini “Sirala” ve Text özelliğini “Sırala” olarak ayarlamıştır. Hal bu ki Selection Sort algoritmasınından yararlanıp sıralama yaparken yazılacak kodu işletirken kullanılacak Button nesnesinin başlığını Sırala olarak ayarlama hakkı yerli bir yazarın inhisarındadır. Memik Yanık bu düğmeye başlık metni seçerken başka C# kitaplarından esinlenmemiş olsaydı en azında bu düğmenin başlığına “Sort Et Kardaş” veya “Boy Sırasına Sok” gibi akılda kalıcı olmayan bir şeyler aktarabilirdi. 

Şimdi gelin yazının başlığında işaret edilip yeniden sonradan yapılan buluştan biraz söz edelim. 2003 yılında yerli yazarımız gece gündüz çalışıp Selection Sort algoritmasını geliştirip bir kitabı aracılığıyla bilişim dünyasına hediye etmiştir. 25 yıl aradan sonra tekrar geliştirdikleri bu algoritmaya “En Hakiki Selection Sort algoritması” adını vermelerini teklif ediyorum. Çünkü yıllar önce geliştirilen Selection Sort algoritması artık eskimişti. Bu buluşu yazılım dünyasına hediye etmelerine hediye etmişlerdir de bu buluştan programcılık kitaplarında söz etme, anlatma hakkını kendilerine saklamışlardır. Bakalım Memik Yanık kitabında sıralama yapmak üzere nasıl bir kod yazmıştır.

p
rivatevoid Sirala_Click(object sender, EventArgs e)
   {
       int[] dizi;
       int i, j;
       int gecici, eleman;
       eleman = listBox1.Items.Count;
       dizi = new int[eleman];
       for (i = 0; i <= eleman - 1; i++)
         dizi[i] = Convert.ToInt32(listBox1.Items[i].ToString());
       for (i = 0; i <= eleman - 1; i++)
          {
            for (j = 0; j <= eleman - 1; j++)
              {
                 if (dizi[j] > dizi[i])
                  {
                      gecici = dizi[i];
                      dizi[i] = dizi[j];
                      dizi[j] = gecici; 
                  }
              }
          }
          for (i = 0; i<=eleman - 1; i++)
             listBox2.Items.Add(dizi[i].ToString());    
        }
    }

Şu koda bakın ki baştan sona esinleme kokuyor. Dakka bir gol bir misali Memik Yanık bu kodda "dizi" adında bir dizi değişken tanımlayıp başkalarına ait olan bu değişken adını kullanmıştır. Çünkü dizi’yi değişken adı olarak kullanmak bu buluşçu yerli yazarımızın kitabı çıkmadan önce kimseye nasip olmamıştı. Her ne kadar daha önce yayınlanan çok sayıda programcılık kitabında "dizi" adında dizi değişken tanımlanmış olsa bile bu hak 2004 yılından itibaren bu algoritmayı yeniden bulan yerli yazara geçmiştir.

Memik Yanık kitabında dizi adında dizi değişken tanımlama kabahatini işlemekle de yetinmemiştir ve kısacık kodda başkalarına ait olan i ve j’yi değişken adı olarak kullanmıştır. Memik Yanık’ın bu kodda tanımladığı "gecici" ve "eleman" adlı değişkenlerin adının sahibi var mıdır yok mudur henüz belli değildir. Bu değişkenlerin sahipleri ortaya çıkıp açıklama yaparlarsa insanlar başkasına ait değişken adlarını kullanıp kul hakkı yemezler.

Memik Yanık bu kodu yazarken dizi, i ve j değişkenlerinin adını başka kaynaklardan çaldıktan sonra bir yerlerden esinlenip formdaki ilk ListBox’ın elemanlarını bu dizi değişkene aktarmayı akıl etmiştir. Tanımladığı dizi değişken int tipinde olduğu için dünyadan yalnızca bir programcılık kitabı yazarı tarafından bilinen Convert sınıfının ToInt32() metodu ile ListBox’ın elemanlarını int tipine dönüştürüp dizi adlı dizi değişkene aktarmıştır. Sizce Memik Yanık bu işlemi başka yazarların kitabından esinlenmeden yapabilir mi? Bence yapmazdı.

Memik Yanık yazıp kitabında kullandığı kodun devamında yerli yazar tarafından 2003 yılında yeniden geliştirilen Hakiki Selection Sort algoritmasını izinsiz bir şekilde kullanmıştır. İşte size bu algoritmanın sıralama yapan asıl satırları:

gecici = dizi[i];
dizi[i] = dizi[j];
dizi[j] = gecici; 
 

Boşuna aramayın yerli yazarımızın kitabından yararlanmadan bu 3 satırı yazacak kimse dünyada yoktur. Dolayısıyla Memik Yanık kitabında bu 3 satıra yer verdiyse kesin esinleme yapmıştır, izinsiz alıntı yapmıştır. Her ne kadar Memik Yanık kitabında yukarıda verilen kodu verme nedeni iç içe for döngülerinden söz etmek olsa bile biraz akıllı davranıp sıralama işlemini iç içe for yerine iç-içe while döngüleriyle yapabilirdi. Tabii başkalarına ait i, j, dizi gibi değişken adlarını kullanmamak şartıyla.

 private void sirala_2_Click(object sender, EventArgs e)
  {
     int[] dizi;
     int i = 0;
     int j = 0;
     int gecici, eleman;
     eleman = listBox1.Items.Count;
     dizi = new int[eleman];
     for (i = 0; i <= eleman - 1; i++)
       dizi[i] = Convert.ToInt32(listBox1.Items[i].ToString());
     i = 0;
     while (i <= eleman - 1)
        {
          j = 0;
         while (j <= eleman - 1) 
          {
             if (dizi[j] > dizi[i])
                {
                   gecici = dizi[i];
                   dizi[i] = dizi[j];
                   dizi[j] = gecici;
                }
               j = j + 1;
         }
          i = i + 1;                                    
       }
      for (i = 0; i<=eleman - 1; i++)
          listBox2.Items.Add(dizi[i].ToString());    
     }
  }

Memik Yanık’ın kabahatinin hem başkalarına ait değişkenleri hem de 2003 yılında yerli bir yazar tarafından keşfedilen Selection Sort algoritmasını C# kitabında kullanmakla sınırlı olduğunu sanıyorsanız yanılıyorsunuz: Memik Yanık bu algoritmayı ve birileri tarafından kapatılmış değişkenlari Delphi 7 kitabında da kullanmıştır. Alın size Memik Yanık’ın Delphi 7 kitabından alınma bir ekran görüntüsü.



Gördüğünüz gibi Memik Yanık bu kitabında da iç içe for döngülerini anlatmak için yine Selection Sort algoritmasından yararlanmayı tercih etmiştir. Ancak bu kez forma düğme yerleştirmeyip düğme başlığı metnini başka kaynaklardan çalmamıştır. Bu durumda sıralamayı yapacak kodu formun Click olayını temsil eden metoda yazmıştır. Verilen kodu yakından incelediğinizde Memik Yanık yine "dizi" adında bir dizi değişken yine i ve j adında 2 integer tipinde değişken tanımlamıştır.



Bu yazıyı bitirmeden buradan size bir çağrıda bulunmak istiyorum: Bu algoritmayı geliştiren yerli yazarlara destek olmak için bu algoritmanın dünyaya ilk duyurulduğu C# kitabından üçer beşer adet satın almanızı öneriyorum. Bu sayede Türkiye bilişim alanında çağ atlama şansı yakalar. Hem bu buluşun dünyaya açıklandığı kitaptan 3 tane alanlara i’yi, j’yi ve dizi’yi değişken adı olarak kullanma hakkı elde ediyorlar.

Bu yazıya 1 yorum yapılmış. | 16.05.2009 19:12:19

Dünyanın Sanat Değeri En Yüksek Windows Formu


Herkesin bildiği gibi yerli ve yabancı programcılık kitaplarında verilen örneklerle ilgili olarak hazırlanan formlarda tasarıma pek önem verilmez. Çünkü yazarın amacı sözünü ettiği işlemi anlatmaktır, kullandığı sınıf veya kontrol hakkında bilgi vermektir. Örneğin 2004 yılında yayınlanan C# kitabımda foreach döngülerinden söz etmek için forma bir RichTextBox, ListBox ve bir düğme yerleştirdim.



Kitabımda bu örneği vermemdeki amaç foreach döngüsünü anlatmak olduğu için birer koleksiyona sahip RichTextBox ve ListBox nesnelerini tercih ettim. Çünkü foreach deyimi koleksiyonların elemanları elde edilirken kullanılmaktadır. Kullanıcı çalışma anında RichTextBox'a girdiği metni ListBox'a aktarmak istediğinde adı ve başlığını "Aktar" olarak ayarladığım düğmeyi tıklayacak. Buraya kadar her şey normal ve ilginizi çekecek orijinal bir durum yoktur.

Gelelim asıl konumuza: Memik Yanık kitabında yukarıdaki gibi orijinal bir tarafı ve sanat değeri olmayan bir form tasarlarken mesleğinin zirvesine çıkmış başka bir yerli yazar yazılım dünyasına öncülük edip kitabında sürekli sanat değeri yüksek form tasarımlarına yer vermektedir. Mesleğinin zirvesine çıkmış bu yerli yazarın kitabında kullandığı bir form var ki dünyanın 8. ci harikası olmaya adaydır. Olağanüstü güzellikteki bu formu küçük değişikliklerle aşağıda verdim.



Yerli yazarımız bu güzellikte form tasarlayınca ister istemez bundan etkilenen yazarlar olacaktır. Bu olağanüstü güzellikteki form tasarımdan etkilenenlerden birisi Memik Yanık’tır. Memik Yanık yukarıda verilen formu tasarlarken sanat değeri yüksek bu formdan esinlenip her şeyi ile aynı bir form hazırlayıp kitabında kullanmıştır. Üstelik Memik Yanık’ın üstünkörü tasarladığı formun sol üst köşesinde tıpkı yukarıda verilen sanat değeriyle fark yaratan form gibi Kontrol Menüsü vardır. İşin garip tarafı kitapta gösterilmese bile bu menülerin açılmış hali verilmiş olunsaydı görülürdü ki her form tasarımın bu menüsünde aynı komutlar vardır. Memik Yanık özensizce tasarlayıp kitabında kullandığı formun Kontrol Menüsünde yerleştirdiği komutların adları ve işlevlerini seçerken yaratıcı olmamıştır(!) ve sanat değeri yüksek rakip yazarın kitabından esinlenmiştir. 

Şimdi bazıları çıkıp diyecekler ki bu iki ekran görüntüsünün yani formun nesi benzerdir, mesleğinin zirvesindeki yazarın tasarlayıp kitabında kullandığı bu formun neresi dünyanın 8. harikasına adaydır diye soracaklardır. 

Bu itirazcılara cevabım hazır. Bu form arasındaki benzerlikler saymakla bitmez. İşte birkaç benzerlik: Her iki ekran görüntüsünün sağ üst köşesinde Simge Durumuna Küçült, Ekranı Kapla ve Kapat düğmeleri bulunmaktadır. Memik Yanık bu sanat değeri yüksek formdan esinlenmemiş olsaydı formun sağ üst köşesine bu düğme yerine başka düğmeler yerleştirirdi. Örneğin Memik Yanık kitabında kullandığı formun sağ üst köşesinde neden Ekran Kapla düğmesi yerine “Penaltı Çek”, “Smaç Yap”, “Yemek Ye” gibi adlara sahip düğmeler yerleştirmemiştir? 

Bazı programcı ustaları çıkıp form tasarımlarının sol üst köşesine yerleştirilen denetim düğmesiyle açılan menüde yer alacak komutları programcı değil Windows belirliyor diye itiraz edeceklerdir. Bu itirazcılara cevabım şudur: Gidin bu olağanüstü güzellikte tasarıma sahip formlarla dolu kitaplardan üçer beşer tane alın da programcılık öğrenin ve programcılıkta zirveye çıkın.

Bu 2 ekran görüntüsünün bir birisinin tıpkısı olduğuna itiraz edenlere ikinci söyleyeceğim şudur: Sizler Ankara’da köklü bir üniversitede Prof unvanına sahip öğretim üyesinden iyi mi bileceksiniz? Sizler 10 yıldır Ankara’nın merkezinde on binlerce kişiye programcılık öğretmiş bilgisayar kursu sahibi bilgisayar mühendisinden iyi mi bileceksiniz? Sizler Türkiye’nin en eski derneğinde yönetim kurulu üyeliğine kadar yükselip milyonlarca dolarlık projelere imza atan tecrübeli bilgisayar mühendisinden iyi mi bileceksiniz?

Bana sorulursa bu ekran 2 görüntüsünün benzer olduğunu rapor eden bilgisayar mühendisinin sahibi olduğu kurs Ankara'nın 1 numaralı bilgisayar kursu ilan edilmelidirler. Bu 2 ekran görüntüsünün benzer olduğunu ileri süren Bilişim Derneğinin yönetim kurulu üyesi hiç zaman geçirilmeden dernek başkanı yapılmalıdır. Ayrıca bu 2 ekran görüntüsünün benzer olduğunu rapor eden Prof unvanlı öğretim üyesi hemen görev yaptığı üniversitede derhal rektör yapılmalıdır. Ayrıca Nobel bilim ödülüne aday gösterilmelidir. Nobel edebiyat ödülünden sonra bir Türkün Nobel Bilim Ödülü alması fena mı olur?

Bu yazıya henüz yorum yapılmamış. | 15.05.2009 19:31:56

Değişken Adı Sahiplerine Duyuru(*)


.NET Framework 3.5 ve C# 3.0’ı temel aldığım yeni C# kitabım sonunda yayınlandı. Yaklaşık 1100 sayfa olan bu kitabımı aslında Haziran ayında tamamlayıp aydınger çıkışlarını almıştım. Sonra ikinci kez suçlanmamak için kitapta değişken adı tadilatına gitmiştim. Örneğin önceden “Toplam” adını verdiğim değişkene sonradan “Yekun” adını verdim. Benzer şekilde alışkanlıklarım gereği sayi1, sayi2 adlarını verdiğim değişkenlerin adlarını Number1, Number2 olarak değiştirdim. Hatta kitapta değişken adının önemine(!) okurlarını dikkatini çekmek için 3 satırlık kodu 2 kez verip değişkenlere Sayi1, Sayi2 gibi adlar verilmeden 2 sayıyı birbirine bölmenin mümkün olduğunu kanıtlamaya çalıştım. Aşağıda verdiğim kodu kitabın değişken tadilatından önceki halinde bulunuyordu. 

private void Hesapla_Click(object sender, EventArgs e)
 
 { 
   byte Sayi1 = Convert.ToByte(textBox1.Text); 
   byte Sayi2 = Convert.ToByte(textBox2.Text); 
   float Sayi3 = Sayi1 / Sayi2; 
   textBox3.Text = Sayi3.ToString(); 
 }

Uzun araştırmalar(!) sonucu bu 4 satırlık kod aşağıdaki düzenlendiğinde bile aynı sonucu verdiğini tespit ettim. Bu tespitten yola çıkarak programcılara şunu önermek istiyorum: Elinizde bir birine bölmek istediğiniz 2 sayı varken tanımlamanız gereken değişkenlere Sayi1, Sayi2 gibi adlar vermezseniz bile yazacağınız kod çalışıyor. Yani madem kapatılmış veya register edilmiş değişkenleri kullanmanın size bir artısı yok bunları kullanıp suçlu durumuna düşmenin alemi yoktur. 

private void Hesapla_Click(object sender, EventArgs e)

{ 
  byte Number1 = Convert.ToByte(textBox1.Text); 
  byte Number2 = Convert.ToByte(textBox2.Text); 
  float Number3 = Number1 / Number2; 
   textBox3.Text = Number3.ToString();
}

Kitapta değişken adı tadilatına gitmiş olmama rağmen olur ya kitabın bir yerinde i, j, dosya vs gibi sahipli değişkenleri farkında olmadan kullandıysam bu değişkenlerin sahipleri beni aradıklarında kitap tekrar basıldığında bu değişkenlere İngilizce, olmadı Osmanlıca karşılıklar bulurum.Yukarı çağrıyı değişken adı sahipleri için yapmış olsam bile aynı çağrıyı Button, ListBox nesnesi veya metot adı sahipleri için de yapmak gerekir. Olur ya dalgınlık eseri kitabımda kullandığım Button nesnelerine Button1, Button2 gibi adlar dururken "Aktar" gibi sahiplenmiş bir adı verdiysem suçlanmaktan kurtulmak için şimdiden tedbir almalıyım.
* Bu metni 2008 yılı Aralık ayında kaleme aldım.

Bu yazıya henüz yorum yapılmamış. | 15.05.2009 00:55:51

Microsoft Türkiye Yetkililerine Sorularım Var..


Yetkililere sorumu yöneltmeden önce biraz açıklama yapmak istiyorum. Son yıllarda programcılıkla az çok ilgilenmiş olanların bildiği gibi Microsoft firması 2002 yılından önce yani .NET kullanıma sunulmadan önce veritabanı işlemleri için programcılara ADO teknolojisini öneriyordu. Tabii Visual Basic 3.0 ve Visual Basic 4.0’ın kullanıldığı günlerde DAO ve RDO teknolojilerini unutmamak gerek. Sonra Microsoft firması .NET’i duyurunca daha önce ADO kullanan programcılar kısa sayılmayacak bir süre şaşkınlık yaşadılar. Çünkü .NET Framework ile gelen ve ADO.NET adı verilen sınıflarla veritabanı işlemlerinin neredeyse ADO ile hiçbir benzerliği yoktu. Programcılar üzerinde işlem yapmak istedikleri veritabanı Access ise OleDbConnection sınıfından yararlanıp veritabanına bağlanıyorlar. Tabii OleDbConnection sınıfı sayesinde bağlanılabilinen tek veritabanı Access değildir. Programcı SQL Server veritabanına bağlanmak istediğinde ise .NET Framework ile gelen SqlConnection sınıfından yararlanması gerekiyor. Bu konunun meraklıları için forma yerleştirilen SqlConnection nesnesinin ConnectionString özelliğinin nasıl ayarlanıp ilgili veritabanına nasıl bağlanıldığını aşağıda göstermeye çalıştım.

 
private void Baglan_Click(object sender, EventArgs e)
 {
     string Segment1, Segment2, Segment3, Segment4;
     Segment1 = "Data Source=SERVER;";
     Segment2 ="Initial Catalog=Galeri;";
     Segment3 = "User ID=*****;";
     Segment4 = "Password=******;";
     sqlConnection1.ConnectionString=Segment1+Segment2+Segment3+ Segment4;  
     sqlConnection1.Open();
 }

Tabii bu kodda bağlantı metni ile ilgili bütün ayrıntılara yer vermedim. SqlConnection nesnesinin ConnectionString özelliği bu şekilde ayarlanıp Open() metodu ile veritabanına bağlanıldıktan sonra sırada forma SqlDataAdapter nesnesini yerleştirip özelliklerini ayarlamak var. Konuya uzak olmayanların bildiği gibi forma SqlDataAdapter nesnesi yerleştirilip yerleştirilmez Data Adapter Configuration Wizard çalışmaya başlamaktadır. Wizard’ın programcıya birkaç soru sorduğunu biliyorsunuz. Buraya kadar her şey tamam. Benim sorum veya sorunum tam bu noktada başlıyor; 

Soru 1:

DataSet hazırlamak üzere Properties penceresindeki ilgili linki tıklar veya Visual Studio’nun Data menüsünden  Generate DataSet komutunu verirsem suç işlemiş olur muyum? Yani Microsoft firmasının sayın yöneticileri kitaplarda, makalelerde, forumlarda Generate DataSet komutu ile DataSet hazırlama, anlatma, bu konuda bilgi verme hakkını Türkiye sınırları içerisinde ihale yoluyla veya başka bir yöntemle herhangi bir kuruma veya kişilere verdiniz mi? Eğer Generate DataSet komutunu kullanma hakkını birilerine ücreti karşılığında vermediyseniz birileri sizin adınızı kullanıyor demektir.

Soru 2:

Dataset nesnesi bir şekilde hazırlandıktan sonra SqlDataAdapter sınıfının Fill() metodunu kullanabilecekler ve Fill() metodu hakkında açıklama yapabilecekler listesinde Memik Yanık var mı? 

Soru 3:

Malumunuz olduğu üzere sık kullanılan SQL kodları daha sonra kullanılmak üzere veritabanına Stored Procedure olarak kaydedilir. Yine her Strored Procedure yazmış kullanmış olanlar bilirki Stored procedure'ler dışarı ile(yani uygulamayla) parametreler aracılığı ile haberleşirler ve parametrelerin yönü ya Input ya da Output olur. Edindiğim bilgilere göre yönü OutPut olan parametreleri kullanmak suç teşkil ediyormuş? Microsoft'un sayın yetkilileri yönü Output olan parametreleri Stoed Procedure'lerde tanımlayıp kullanmak suç mudur değil midir? Lütfen resmi açıklama yapın.

Soru 4:

Yeni bildiğiniz gibi(elbette en iyi siz bileceksiniz Visual Studio'yu, .NET Framework ve C#'ı sizler hazırladınız) Properties penceresinde herhangi bir SqlDataAdapter nesnesinin özellikleri listelenirken Generate DataSet linki olmakta ve bu link tıklandığında Visual Studio bir DataSet hazırlamaktadır. Geri planda ise bir XSD uzantılı şema dosyası hazırlanıp projeye ait klasöre konulmaktadır. Eğer Dataset'te birden fazla DataTable varsa bu şema dosyasından yararlanarak hiç kod yazmadan DataTable'lar arasında ilişki kurulabilmektedir. Size sorum şu:Anlatılan şekilde DataTable'lar arasında ilişki kurabilme hakkını Türkiye'de bir grubu ihale yoluyla devredip sonra da programcılar tembelliğe alışıyor açıklaması yaptınız mı? Umarım bilgi edinme yasası çerçevesinde bu işin doğrusunu öğrenebiliriz. Yok biz bu şekilde DataTable'lar arasında ilişki kurma tekniğinden herkes yararlanabilir diyorsanız bunu kamuoyuna duyurmanızı talep ediyorum. 

Bu soru ve konular benim için hayati öneme sahip olduğu için lütfen hemen cevaplayınız. Microsoft Türkiye’nin sayın yetkilileri size sormak istediğim birkaç soru daha olmasına rağmen şimdilik bu 4 soruyla yetiniyorum.

Bu yazıya henüz yorum yapılmamış. | 12.04.2009 23:53:12

Gençlere Yazarlık Önerileri


Bazen kitap yazmak isteyen arkadaşlar benden öneri isterler. Ben de kendilerine mevcut bilgilerimi aktarıyorum. Bilgisayar kitaplarının satışları son yıllarda iyice düşmüş olmasına rağmen birçok arkadaş kitap yazıp yayınlatmak istiyor. Bu arkadaşları düşünerek birkaç öneride bulunmak istiyorum.  

·      Forumları olan Türkçe programcılık sitelerinin hepsini tespit edip Browser programınızın Sık Kullanılanlar listesine mutlaka ekleyiniz.

·       Benzer çalışmayı kitap satış siteleri için de yapın.

·       Kendinize çok sayıda e-mail adresi alın ve bunları şifreleriyle bir yere not edin. Yoksa o kadar e-mail adresini nasıl aklınızda tutmanız zor olacaktır. Aynı şekilde kendiniz için kimsenin aklına gelmeyecek çok sayıda nick tespit edin.

·       Kitabınız henüz yayınlanmamış iken bile forumları ve kitap satış sitelerini sürekli dolaşıp rakip yazarları bir güzel karalayın.

·       Kitabınız yayınlandıktan sonra rakip yazarları karalamaktan öte kendi kitabınızı güzel bir şekilde övün. Tabii işi abartıp kimsenin şüphelenmemesine dikkat edin.

·      Olur ya birileri kitabınız hakkında ileri geri konuşursa, bir şeyler yazarsa hemen dava edin. Böylece kimse sizin kitabınız hakkında olumsuz sözler edemez. Yani kitap yayınlanmadan önce avukatınız hazır olsun.

·      İster programcılıktan anlasın ister anlamasın kitabınız için ünvanı olan bir kaç kişiden birkaç cümlelik önsöz alın. Bu önsöz yazan kişiler size mutlaka teşekkür etsin, bilişim alanındaki çabalarınızı taktir etsinler. Bu kişilerin kitabın içeriği hakkında bilgi sahibi olması şart değildir. Örneğin .NET'in internet kelimesinin üç harfi olduğunu sanan birisinden önsöz metni istenebilir.

·       Birden fazla kitap yayınlamayı düşünüyorsanız kendinizi bir takma isim bulun. Örneğin Ankara Boğaları, Everest'in Gediklileri, Super Beyinliler Ekibi, Hep 90'a Takanlar, All Star'lar vs olabilir.

·       Kitabınız yayınlandıktan sonra aynı konuda başka yazarlar tarafından(yerli yabancı fark etmez) yazılan kitapları didik didik edin, size ait değişken adlarını kullanmışlarsa affetmeyin. Sizin değişkenlerin adını kullanmışlarsa değişken adı kullanma kirası isteyin. Yok derlerse dava edin.

·      Genç şairleri taklit edip eski yazarlara saldırın, onlar hakkında orada burada konuşup puan kazanmaya bakın. Mesela eski yazarların çeviri yaptıkları dedikodusunu yayın, kitapları beş para etmez deyin. 

·       Kitabınızın düzeyi başlangıç olsa bile bunu kesinlikle ret edin ve ileri düzey olduğunu savunun. Kamuflaj için ileri düzey diye anılan birkaç konuyu üçer beşer sayfa ile geçiştirin. Bu ileri düzey diye bilinen konu adlarını mutlaka kitap kapağına yazın.

·       Cümlerinizin hatasız olmasına çalışıp zaman kaybetmeyin. Zamanınızı bir kısmını mutlaka başka yazarlara saldırarak geçirin.

Bu yazıya 2 yorum yapılmış. | 12.04.2009 23:44:33

Programcılar İçin Yazarlık Dersleri : 1


Konu ister programcılık ister edebiyat ister bilim ister siyaset olsun bazı yazarların yazdığı köşe yazısını, makaleyi, romanı veya incelemeyi kolay okursunuz. Yazıyı okuyup bitirdiğinizde harpten çıkmış gibi kendinizi yorgun hissetmezsiniz. Bazı yazarların yazdıklarını ise kendinizi zorlamanıza rağmen yazının sonunu getiremeyip yarıda kesersiniz. Kolay okunan, okuru yormayan yazılar yazmanın tek ve geçerli bir formülü olmasa bile en önemli nokta kurulan cümlelerin yapısıdır. Kurulan cümlede yazar birden fazla şeyi söylemeyi deniyorsa o cümle için okurun en az 2 kat çaba harcaması gerekir. Bazı yazarlar alışkanlıkları gereği kurdukları her cümle tek başına okunabilecek yalınlıktadır. Bazı yazarlar ise uzun ve karmaşık cümleler kurarlar ki cümlenin başında söyleneni cümlenin sonuna varmadan unutursunuz. Bu makale dizisinde kolay okunma konusunda örnek yazılar ve cümleler üzerinde durmak yerine kendi yazdıklarımı bu bağlamda değerlendireceğim. 

Madem bu incelemede birincil hedef okurlarımız programcılardır, yazılım üzerine bir şeyler yazanlardır o halde programcılar veya programcı adayları için birkaç cümleyi öncelikle yazalım. Bana sorarsanız en başta şunu bilmek gerekir: Programcılık ile programcılık üzerine yazmak birbirine sanıldığı kadar yakın faaliyetler değildir. Yani iyi programcı olmakla iyi makale veya programcılık konulu kitap yazmak arasında doğrudan bir ilişki yoktur. İyi yazar olabilmek veya programcılık üzerine iyi kitap, iyi makale yazabilmek için birinci şart; söz konusu programlama dilini iyi bilmek ve genel programcılık bilgisinin yeterli olmasıdır. İkinci önemli şart; yazma, hikâye etme becerisinin olmasıdır. Yazma, hikaye etme veya anlatma becerinizin olup olmadığını anlamanın en kestirme yolu akşam TV’de bir magazin programında İbo Tatlıses veya bir başkası ile ilgili haberi dikkatle izleyip sonra oturup sanki bir gazetenin magazin muhabiriymiş gibi haber yazmaktır. Ardından yazdığınız haberi ertesi gün ki gazetelerin magazin sayfalarındaki haberler ile karşılaştırıp yazdığınız haberin gazetede yayınlananlara benzeyip benzemediğini kontrol etmek gerekir. Eğer gazetelerdeki haber ile, sizin kaleme aldığınız metin benzerlik gösteriyorsa sizin yazma beceriniz vardır denilebilir. Yazdığınız haber metni gazetede yayınlanabilir gibi duruyorsa yazma beceriniz iyidir denilebilir.

Malumunuz olduğu üzere Hata Yakalamak ve Exception Sınıfları adını verdiğim uzunca makalemi bir süre önce sizlerle paylaşmıştım. Sözünü ettiğim makaleyi henüz okumamış olanlar şuradan okuyabilir veya şuradan PDF olarak indirebilirler. C# ve .NET programcılığına ilgi duymuyorsanız bile programcılık gibi teknik bir konunun nasıl anlatılabileceğini merak ediyorsanız yukarıda işaret ettiğim yazıyı baştan sona okuyacak zamanınız yoksa veya C#’a ilgi duymuyorsanız en azından şöyle bir göz gezdirebilirsiniz. Herhangi bir fakültede veya yüksek okulda fizik, matematik, istatistik gibi zor anlaşılan, ötesi takibi zor bir konuyu anlatıyorsanız sözünü ettiğim makaleyi ve “Yazarlık Dersleri” başlığını verdiğim bu metinleri incelemenizi öneririm.

Başka bir anlatımla bu uzunca makale dizisinde veya incelemede Hata Yakalama ve Exception Sınıfları adlı makalemden(bu makale programcılık dersleri boyunca örnek alacağım makalelerden yalnızca birisidir) yola çıkıp meraklılara teknik bir konunun nasıl anlatılacağını, anlatılanların nasıl kolay okunacağını, konu içinde tekrarlar yapılmasına rağmen okurun sıkılmaması için nelerin yapılması gerektiğini kendimce anlatacağım. 

Aslında bu konu üzerinde uzun süre çalışılması gereken bir konudur. Yukarıda sözünü ettiğim makaleyi kişisel web sitemde ilgilenen herkesle paylaştığım için bu çalışmayı öncelikle bu makale bağlamında yaptım. Nasıl ki DVD’si hazırlanan sinema filmlerinin kamera arkası görüntüleri izleyicilere sunuluyor bundan sonra yazacağım kitapların yazılma süreci ilgili açıklamaları okurlarla paylaşmayı düşünüyorum. Tabii böylesi bir paylaşma kitapların yazımı için gereken sürenin artmasına neden olacaktır. Ötesi böyle bir çalışmanın başka bir etkisi olacaktır: Yazımını tamamladığım herhangi bir bölüm üzerine konuşmaya, ek açıklamalar getirmeye başladığımda aklıma yeni soru ve çözümlerin gelmesi, geri dönüp üzerinde konuştuğum metni değiştirmeyi tercih etmem uzak bir ihtimal olmayacaktır. 

Benzer çalışmayı başka yazarların kitapları ve makaleleri için de yapmak mümkündür. Ne yazık ki okurlar başka bir yazarın(hem de rakip bir yazarın) kitabı veya makalesi üzerine konuşmamı yazmamı onaylamıyor. Takma isimlerle yazı yazmak, forumlarda takma isimle boy göstermek ise çölde kendini gizlemeye çalışmak gibi zordur. 

Tam bu noktada genç yazarlara veya yazar adaylarına bir öneride bulunmak istiyorum: Çok az yazar yazdığı cümleyi, makaleyi veya kitap metnini sonradan değiştirmez. Bu nedenle yazdıklarınızı en azından aradan birkaç saat geçtikten sonra tekrar gözden geçmelisiniz. Göreceksiniz ki birçok cümleyi değiştirmek isteyecekseniz. Hatasız, bozuk cümlesiz makaleler yazmak çok zordur ama yazım hatalarını belli bir sayıda tutmaya çalışmak gerekir. Okurlar yazım hataları ile sık karşılaşmadıkları sürece hoşgörülü davranıyorlar.
 

Bu metni gören bazı arkadaşlar uzun olduğu için tümünü okumayacaklardır. Madem incelemenin üst başlığı “Yazarlık Dersleri” ve yazarlık sabırla araştırma yapmayı gerektiren bir eylem olduğuna göre yazarların, yazar adaylarının bu metni ve ilgi alanlarına giren yazıları sabırla okumaları gerekir. Okumayı araştırmayı sürekli öğrenmeyi günlük yaşamlarının doğal eylemlerine katmayanların bırakın yazar olmayı uzun vadede programcı olarak kalmaları zordur.  

Şu aralar memleketimin on binlerce insanı kendine blog edinip yazarlığa kolay yoldan terfi ediyor. Üstelik programcılık konulu blogların sayısı hiç az değil. O zaman bu incelemeye ilgi duyacak on binlerce kişi olmalıdır. Meraktan bazen bu bloglara bakıyorum; bazen öyle kötü kaleme alınmış metinlerle karşılaşıyorum ki 2 cümlesini bile okumak mümkün olmuyor. Keşke bu arkadaşlar yazdıklarına dönüp baksalar. Sanılmasın ki bu söylediğim henüz yolun başında olup meraktan bloğunu doldurmak isteyen arkadaşlarla sınırlı. Hayır, koca koca kitaplara imza atan yazarların bile kitaplarındaki bozuk cümleleri okumak bazen işkence olabiliyor. 

Daha önce C# veya .NET Framework uyumlu başka bir programlama dili üzerine çalışıp hata yakalama ve Exception sınıflarından bi haber olmayanlar yukarıda sözünü ettiğim makaleyi okuduklarında tek kazançları olsa olsa anlatım tekniği üzerinde düşünmek olabilir. C# ve .NET’le gelen Exception sınıfları konusunda en azından ortalama bilgisi olanlara şunu söylemek isterim: Bu metni doktora öğrencilerini değil, programcı adaylarını düşünerek yazdım. Bazen çok iyi bildiğim konularda bile elimdeki mevcut kaynakları gözden geçiririm. Bu gözden geçirmelerin tek nedeni var: İyi bildiğim bu konuyu anlatırken okuduklarım bana belki yeni bakış açısı kazandırır. Yani demek istiyorum ki asıl önemli olan konuyu anlatma ve hikâye etme tarzıdır. Konu ‘programcılık’ anlatmak olduğunda bazı konular vardır ki önce sonucu gösterir sonra adım adım geriye gidip o sonucu nasıl aldığınızı anlatırsınız. 

Kısa bir özet geçmek gerekirse yukarıda sözünü ettiğim makaleyi sonradan gözden geçirmek zorunda kaldığım C# 3.0 kitabımdan almıştım. Kitabı gözden geçirme nedenimi merak edenlere şunu söylemek isterim: Kitapta bazı metotları, sınıfları veya işlemleri anlatmak için hazırladığım 3–5 satırlık kodlarda tanımladığım değişkenlere, hazırladığım metotlara verdiğim adları register(!) edilmemiş değişken adlarından seçme kaygım ağır bastı. Madem yasal nedenlerden dolayı kitapta değişken adı tadilatına(!) gittim, aydınger çıkışlarını aldığım, önsözünü yayınladığım kitabı yeni baştan ele alıp bazı konuları eklerken, bazı konularda yeni ayrıntılara yer verirken bazı konulara ayırdığım sayfa sayısını azalttım. Bu metni okuyan bazı öğretim üyeleri bana tepki gösterip tereciye tere sattığımı düşünebilirler. Bu işe yıllarını vermiş tecrübeli öğretim üyelerinin bu tepkisini normal karşılamak gerekebilir. Ancak bu memlekette programcılık kitaplarında verilen 3-5 satırlık kodlarda i’nin, j’nin, dosya’nın, sayi1’in, sayi2’nin değişken adı olarak kullanılmış olmasına suç gözüyle bakan prof unvanlı öğretim üyeleri olduğunu da unutmamak gerekir. 

Hedef Okur Grubu Seçmek

İşini ciddiye alan, yazma becerisine ve bilgisine güvenen yazar, yazmaya karar verdiği kitabının veya makalesinin üzerinde çalışmaya başlamadan önce kendine bir hedef okur grubu seçer. Ardından hedef okur grubunun beklentilerine, ihtiyaçlarına cevap vermeye çalışır. İşini ciddiye almasına rağmen hedef okur grubunu yanlış seçen veya seçtiği hedef okur grubuna uygun kitap yazamayan yazar uzun vadede başarısız olur. 

Tabii bazı yazarlar işin kolayına kaçıp daha önce yayınlanmış bir kitabın kapsamından(aynı yöntem bazen makale yazılırken ve üniversitelerde derslerin içeriği tespit edilirken kullanılıyor) yararlanıp bazı ekleme ve çıkarmalarla kitaplarının içeriklerini tespit ederler. Başka bir anlatımla, bazı yazarlar kitaplarında hangi konulara yer vereceklerini tespit ederken beğendikleri yazarların kitaplarını kendilerine rehber ederler. Örneğin Herbert Schildt’in C# kitabı yerli yabancı bir çok yazar tarafından rehber olarak kabul edilen bir kitaptır. Bu gruba giren yazarları, neyi nasıl yazacakları konusunda kafaları karışık yazarlar olarak değerlendirebilir. Hemen ekleyelim: Bu şekilde kitap yazan yazarların zaman zaman başarılı oldukları görülmektedir. Başka bir deyişle kitabının içeriğine karar verirken başka kitapları kendine rehber eden yazarlar başarılı kitaplar yazabilirler. 

Bir yazarın beğendiği başka bir yazarın kitabını kendine rehber etmesine günlük hayatta şöyle bir örnek verilebilir: Otomobille gitmek istediğiniz yere nasıl gidileceğini bilmiyorsunuz. Bu nedenle birisine soruyorsunuz. Danıştığınız kişi size “şu dolmuşu takip ederek oraya gidebilirsiniz” diyor. Henüz yolun başında olan yazarlar dolmuş takip edip istediklere yere gitmesinler diyecek değilim. Bu konuda sözü hemen kendime getireceğim: Kitaplarını yabancı yazarların kitaplarından gizlice çeviri yaparak yazmakla suçlanan Memik Yanık bırakın çeviri yapmayı şimdiye kadar beğendiği yazarların hiçbir kitabını kendisine rehber yapmadı. Alın size bir örnek Memik Yanık 1994 yılında yayınladığı Clipper adlı ilk kitabını yazarken elinde bir tek yabancı kitap vardı ve yazdığı Clipper 5.2 adlı kitabın elindeki yabancı kitapla en ufak benzerliği yoktu. 

Kitapların içeriklerinin ve konuların sıralanışı bakımından birbirine benzemelerini normal karşılamak gerek. Örneğin birçok programcılık kitabında ilk sayfalarda program geliştirme aracından söz edilir. Yazar program geliştirme aracından söz etmek istiyorsa doğal olan budur. Yine birçok yazar öncelikle değişkenlerden tiplerden blok kontrol deyimlerinden vs söz eder. 

Şimdi 2003 yılına gidip size birkaç cümle ile Memik Yanık’ın 2004 yılında yayınlanan C# kitabı bağlamında Herbert Schildt’in C# kitabı hakkında birkaç cümle yazacağım. Biraz gecikme ile olsa bile C#’la ilgilenmeye başlamıştım. Piyasadaki birkaç Türkçe kitaptan birisi Herbert Schildt tarafından yazılıp Alfa Yayıncılık tarafından Türkçeye çevrilen(çevirmen Selçuk Tüzel) Herkes İçin C# kitabıydı. Kitabı elime alıp biraz incelediğimde beğenmiştim. Bu durumda hemen akla şu soru gelir: Madem dünyaca ünlü bir yazarın kitabı Türkçeye çevrilmiş ve bu kitabı beğeniyorsun o halde neden kendin oturup C# kitabı yazdın? Bu soruya verilecek makul bir cevabım olmasaydı zaten kendim C# kitabı yazmazdım. Çünkü Herbert Schildt’in kitabı çok iyi kitap olmakla birlikte birçok okurun öncelikle gerek duyacağını sandığım konuları içermiyordu. Örneğin veritabanı yani ADO.NET konuları yok gibiydi. Ötesi Visual Studio’dan yararlanma konusunda neredeyse sıfır bilgi içeriyordu. Bu durumda yazmam gereken C# kitabı Herbert Schildt’in kitabının rakibi olmayıp bıraktığı boşluğu doldurmaya çalışmalıydı. Hatta o günlerde Herbert Schildt’in C# kitabı ile hemen hemen aynı konuları içeren, aynı anlayışla kaleme alınmış başka kitaplar yayınlanmışken Herbert Schildt’in kitabına benzeyen 3. 4. bir C# kitabı yazmam zaten anlamsız olurdu. 

Aynı konuda 2. veya 3. kitabı yazma konusuna bazen şöyle bakmak gerekebilir: Piyasada Türkçe yayınlanmış ve oldukça beğendiğiniz kitaplar olmasına rağmen bu kitapların hedef okur grupları ileri düzey bilgi edinmek isteyenler ise, kendiniz başlangıç düzeyi konuları içeren kitap yazabilirsiniz. Bazen bunun tersi de olur: Piyasada çok iyi başlangıç düzeyi kitaplar vardır ve size göre ileri düzey bilgi edinmek isteyen çok sayıda okur bulunmaktadır. Bu durumda ileri düzey bilgi ihtiyacı olan okurları hedefleyen kitap yazarsanız başarılı olursunuz. 

Bazı yazarlar vardır ki bunu(yani usta bir yazarın kitabını kendine rehber edinmeyi) bile yapmazlar, ellerinde ne malzeme varsa kitaplarına doldururlar. Değişik amaçlar için yazdıkları programları kırpıp kırpıp kitaplarında kullanırlar. Yabancı yazarlar genellikle aynı tablolara sahip ve herkes tarafından bilinen örnek veritabanlarını kullanırken bizim yerli yazarlar ilk bakışta okura karışık gelen veritabanları üzerinde örnekler hazırlarlar. Tabi böyle bir yaklaşımla yazılan kitaplar kafadan kötüdür vs denilmese bile böyle bir anlayışla yazılan kitaplarda “makale toplamı” havası koklanır. Örneğin C# veya Visual Basic.NET konulu bazı kitaplarda Object sınıfından doğru dürüst söz edilmeden ilk sayfadan itibaren Class’lar hakkında derinlemesine bilgi verilmeye başlanır. Tabi bu kitaplarda Object sınıfının bütün sınıfların atası olduğu mutlaka birkaç kez işaret edilir. Yazarımız kitabının hemen başında Object sınıfı hakkında bilgi verse anlaşılmayacak. Object sınıfını kitabının sonlarına bıraksa bu kez başka sorunlar çıkacak. Çözüm kitaba hakim olmaktadır, çözüm okura henüz anlatılmayan sınıflardan söz edilirken okurun konuyu henüz bilmediğini unutmamaktır. 

Hedef okur grubunu doğru seçmeyen yazar nasıl bir anlatım dili kullanacağı konusunda tereddütlere düşer. Örneğin yazarın birisi C# üzerine yazarken arada bir C++ veya C’ye göndermede bulunur. Bunun anlamı şudur: Yazarımız programcılığa ilk adımlarını C# ile atanları değil daha önce C++ veya başka bir programla dili ile 3-5 satır bile olsa kod yazmış olanları hedeflemektedir. Bu durumda yazarımızın bütün kitap boyunca anlatım şeklini programcılık konusunda az çok bilgisini olanlara yönelik yapması gerekir. Tabii konu üzerinde yeterince düşünmeyen ve elindeki malzemeyi kitap olarak değerlendirmek isteyen yazar arkadaşımız; bir sayfada okurunu yıllardır programcılık yapan birisi olarak görüp ona göre cümle kurarken, başka bir sayfada karşısında sanki hayatında tek satır kod yazmamış birisi varmış gibi konusunu anlatır. İşin özü şudur: Yazar iyi kitap yazmak istiyorsa önce hedef okur grubunu tercih edecek. Sonra da kitabını kaleme alırken kitabının her sayfasında hedef okur grubunun beklentilerini ve mevcut bilgi düzeyini gözetecek. 

Bundan yaklaşık 7-8 yıl önceydi. Yıllardır görmediğim arkadaşımı Anamur’da ziyaret etmiştim. Hemen bana Muz ve muzculuk üzerine yazdığı kitabı verdi. Kitabı 10-15 dakika kadar gözden geçirdikten sonra arkadaşa dedim ki(ki muz hakkındaki bilgim muzun Anamur’da yetiştirildiği ile sınırlıdır) “sen iki cami arasında bey namaz kalmışsın. Bir taraftan bu kitap muz üreticilerine yararsın, bir taraftan da üniversitedeki hocaların beğensin istemişsin. Kitabını ya hocaların için ya da Anamur’da muz üretenlerini hedefleyerek kaleme almalıydın. Tercihini baştan yaparsan daha iyi kitap yazarsın”. Tabi bu yorumuma arkadaş şaşırdı. Çünkü asıl sıkıntısına parmak basmıştım. Gelelim programcılık konulu kitaplara:Hedef okuru seçilmeden yazılan kitabın iyi olması tesadüflere bağlıdır.

Önce Kitabın Neyini Yazmak Gerekir?

İşini ciddiye alan yazar ilk olarak kitabının önsöz’ünü yazarak hedeflerini ortaya koyar. Kitabını bitirip kitabı üzerine yazacak bir şeyi olmayan hatta 1 sayfalık önsözü bile yazmakta zorlanan yazarın kitabı hakkında olumlu düşünmek bence zordur. Düşünsenize yazarımız oturup 1000 sayfalık kitap yazıyor ama iş kitabın önsözünü yazmaya gelince klasik bir iki cümle etmekten öteye gidemiyor. İyi programcılık kitabı yazmak veya usta yazar olmak isteyenlere bu konudaki önerim şudur: Önce kitabınızın önsözünü yazın, kitabınızla neyi hedeflediğinizi bir bir ortaya koyun. Sonra kitabın içeriğini doldurdukça mevcut önsöz metninde küçük değişiklikler yapın. Kitabı bitirdiğinizde ilk hedeflerinizin çok ötesinde(yani gerisinde) duruyorsanız tekrar düşünmeniz, hedeflerinizi ve kitabınızı tekrar değerlendirmeniz gerekir. Örnek olması için ilk C# kitabımın önsözünden bir paragrafı buraya aldım. Bu paragrafta ilk C# kitabım için kolay okunma ve okunanın hemen anlaşılması gibi bir hedefimin varlığını işaret ediyorum. 

Bu kitabı yazmaya başlamadan önce yerli-yabancı C# konulu birkaç kitabı inceledim. Bütün kitaplar değişkenler, döngüler, formlar ve diğer konular hakkında anlaşılır şekilde yeterli bilgi içeri­yordu. Ancak konu veritabanı olunca işin rengi değişiyordu; kimisi sanki karşılarında Microsoft’un SQL Server veya başka bir veritabanı programını geliştiren firmanın programcılarının olduğunu sanıyor, kimisinin ise ne anlattığı anlaşılmıyordu. Bu nedenle C#’ın veritabanı özelliklerinin bir okumada hemen anlaşılmasını sağlamak ve kimseyi çok sayıda kitaptan aynı konuyu tekrar tekrar okumak zorunda bırakmamak için bazen konuyu uzattığım oldu. Bu kitapta yazılanların basitliğine ve kolay anla­şılmasına tepki duyanlara “bir kitabı veya bir yazıyı 2. defa okumanın ne kadar sıkıcı olduğunu” hatırlatmak istiyorum. 

Tahmin edersiniz ki bu paragraf yukarıda yaptığım öneriye uygun olarak kitap üzerinde çalışmaya başlamadan önce yazılan hali değildir. Çünkü yazar bazen ilk hedeflerinden biraz uzaklaşır. Örneğin yazar der ki şu bölüm için şu kadar sayfa yeterlidir. Ancak yazarımız konu üzerinde çalışmaya başladıkça, aklına yeni sorunlar ve çözümler geldikçe söz konusu bölüme ayırmak istediği sayfaların sayısının iki katına çıktığını fark eder. Örnek vermek gerekirse şu günlerde tekrar gözden geçirdiğim C# 3.0 kitabıma sonradan Application Domain’ler hakkında birkaç sayfa eklemeye karar verdim. Ancak konu üzerinde çalışıp muhtemel sorulara cevaplar aramaya başlayınca Application Domain konusunu 3 sayfada anlatırsam yazılanların havada kalacağını ve kimseye bir faydasının olmayacağını fark ettim. Şu günlerde karar vermem gerekiyor:Ya C# 3.0 kitabımda Application Domain’lerden söz etmeyeceğim ya da en az 15 sayfa boyuncu konuyu enine boyuna anlatacağım. 

Bazen de bunun tersi olur, 15 sayfa boyunca anlatırım dediğiniz konu için bir bakarsınız ki 6-7 sayfa yeterli olmuş. Ötesi kitabın önsözünü yazarken dersiniz ki “bu kitap ileri düzey diye anılan şu şu konuları içerecek, dolayısıyla ileri düzey bir kitap olacak”. Ancak bazen evdeki hesap çarşıya uymaz. Örneğin değişkenler konusu bütün programcılık kitaplarında bulunur. Yazarın birisi değişkenlere 10 sayfa yer ayırırken bir başkası değişkenleri 20 sayfa boyunca anlatır. C# 2.0 kitabımda değişkenlere ayrılan sayfaların sayısı az değildi. C# 3.0 kitabımın üzerinde çalışmaya başlamadan değişkenlere daha az yer ayırmak gibi bir düşüncem vardı. Ne var ki değişkenler bölümü üzerinde çalışmaya başladıkça sayfaların sayısı artmaya başladı. Çünkü C# kitabımın anlatım düzeyini biraz yükselttiğim için değişkenlerle ilgili olarak zaman zaman teknik açıklamalar yapmaktan geri duramadım. Bu durumda ya kitabın sayfa sayısını arttırmam ya da bazı konuları kitaptan çıkarmam gerekecekti. Yani anlayacağınız kitabın ileri düzey olarak anılmasına neden olacak birkaç konuyu böylece tehlikeye atmış oldum. Kitabın düzeyini düşürmeye razı olmadığım için okurların her kitap veya kaynakta bulacağı bazı konuları kitaptan çıkarmayı tercih ettim. 

Tabi bazı yazarlar tanımladıkları değişkenlere ad verirken rahat davranıyorlar. Bütün programcılar tarafından değişken adı olarak kullanılması alışkanlık olmuş “i”, “j”, “sayi”, “dosya” vs gibi değişken adlarını kullanarak kabahat işlemiş oluyorlar(!) Madem makalenin veya incelemenin başlığı Yazarlık Dersleri, biz de yazar arkadaşları uyaralım ve diyelim ki “kitaplarınızda ve makalelerinizde verdiğiniz kodlarda kullandığınız değişken adları konusunda dikkatli olun, kullanmış olduğunuz değişken adlarını tıpkı alan adları(domain) gibi önceden birileri sahiplenmiş olabilir.” Sahibi olan değişkenleri makalelerinizde(tabii yazılan programlar derlendikten sonra değişkenlere verilen adların önemi kalmadığı için bu sözümüz yalnızca kitap ve makale yazanlaradır) kullanırsanız Memik Yanık gibi suçlu duruma düşebilirsiniz. 

Bu noktada ek açıklama yapmak istiyorum: Konu programcılık üzerine yazmak olduğunda bazı konularda ön bilgi niyetine kısaca anlatmak soruna neden olmaz. Örneğin .NET uyumlu projelerde serileştirme işleminin nasıl yapıldığını 3 sayfada anlatıp keserseniz bazı okurları tatmin etmesiniz de anlatılanlar anlaşılır. Başka bir deyişle serileştirme ile ilgili işlemlerin ve sınıfların ayrıntılarına girilmeden yazılanları anlamak mümkündür. Tabii serileştirme işleminden söz etmeden önce okuru stream sınıfları hakkında bilgilendirmiş olmanız gerekir.

Biraz da Editörler İçin Yazalım

Türkiye’de henüz tam kurumsallaşmamış olsa bile belli başlı yayınevlerinin editörleri vardır. Editörler programcılık ve bilgisayar üzerine kaleme alınmış kitapları yayınlamadan önce değerlendirip ya yayınlarlar ya da yayınlamama kararı alırlar. Editörlük kurumu özellikle yeni yazarlar için önemlidir. Bu başlıkta sizlere editörleri nasıl ikna edersiniz vs. bilgiler verecek değilim. Asıl üzerinde durmak istediğim konu şudur: Madem bir editör bir kitabı baştan sonra sayfa sayfa cümle cümle okuyamayacağına ve yazarın her yazdığının doğru olup olmadığını test edemeyeceğine göre kendisine gelen dosyayı(yani kitap olacak metinlerin hepsi) önce kuşbakışı inceler. Bazı cümleleri mercek altına alır, yazarın Türkçe bilgisi yeterli midir, cümleleri düzgün mü, yazım hataları kabul edilebilir miktarda mı sorularına cevap arar. Editörün incelediği dosya hakkındaki fikri olumlu ise yani yayınlayabiliriz görüşüne vardıysa, ya kendisi dosyayı daha kapsamlı bir incelemeden geçirir ya da dosyayı o konuda bilgisi olan birisine verir. 

Burada önemsediğim nokta şudur: Konumuz C# olsun. İşin web tarafı var, veritabanı kısmı var, genel programcılık kısmı, Windows’un sağladığı alt yapıyı bilmek var. Çoğunlukla yazarlar birbiri ile bağlantılı bütün konuların uzmanı değillerdir. Örneğin .NET dillerinden birisi üzerine kitap hazırlayan yazarımız .NET Framework ile gelen güvenlikle ilgili sınıfları uzmanlık düzeyinde bilmiyor olabilir. Hatta .NET Framework gelen bazı kontrolleri, sınıfları hiç kullanmamış bile olabilir. Bundan şuna sonuca varmak is