Kötü Kod Nasıl Yazılır?
Yazılım geliştiriciler olarak meslek hayatımızı, her döneminde farklı şeyleri öğrenmenin ve uygulamanın telaşıyla geçiriyoruz. Örneğin ilk yıllarda nesne tabanlı programlamayı öğrenmeye çaba sarfederken, bir süre sonra karmaşık proje yapıları ve katmanlı mimari gibi konuların içinden çıkmaya çalışıyoruz. Birkaç sene sonra servis tabanlı mimari, tasarım kalıpları derken sonrasında kendimizi SOLID gibi prensipleri ne derece doğru uygulayabildiğimizi sorgularken buluyoruz.
Tüm bu uğraşların ve mesleki gelişimin içerisinde öyle bir konu var ki, ister acemi yazılımcı olun ister kıdemli yazılımcı olun peşinizi pek bırakmıyor: Temiz ve anlaşılır kod yazmak. Evet peşinizi bırakmıyor, çünkü aktif olarak 10 yıldır yazılım geliştiren bir yazılımcı bile olsak, 1 sene önce yazdığımız kodları incelediğimizde “kötü kod yazmışım” “burayı daha iyi yazabilirmişim” “kendi yazdığım kodu ben bile anlayamadım”… gibi yorumlar yapabiliyoruz. Ki emin olun 1 sene sonra dönüp bugün yazdığınız kodlara baktığınızda yine benzer yorumları yapacaksınız.
Temiz ve anlaşılır kod yazmak her yazılımcının en temel amaçlarından birisi. Temiz kod yazmakla ilgili bilinmesi, dikkat edilmesi gereken kurallar olduğu gibi dönem dönem yazdığımız kodları gözden geçirip gerekli yerleri refactor etmemiz de gerekiyor.
Kötü kod yazmanın tecrübeyle doğrudan ilişkili olduğunu düşünmüyorum. Acemi yazılımcılar kötü kod yazar diye bir kaide yok, deneyimli yazılımcıların elinden de sıklıkla kötü kodların çıktığını görebilirsiniz. Deneyimlerimden ve çevre gözlemlerimden kötü kod yazmanın bilgi eksikliğinden veya deneyimsizlikten ziyade özensiz, dikkatsiz ve acele yapılan işlerden kaynaklandığını söyleyebilirim. Örneğin müşteri adını temsilen customerName adında bir değişken tanımlamak yerine name diye bir değişken tanımlamak genellikle özensiz ve aceleci bir yaklaşımın sonucudur. “Şimdi kim uzun uzun değişken tanımlayacak” deyip name diye tanımlanan bir değişkene yazılımcı 3 ay sonra baktığında “acaba bu neyin name’i, müşterinin mi personelin mi yoksa şirketin mi…” diyecektir. Hatta 3 ay sonrasına gitmeye gerek yok, o an name değişkenini gören takım arkadaşı da aynı soruyu soracaktır. customerName yerine name şeklinde tanımlanan bir değişken kötü kod yazımına vereceğimiz en basit örneklerden biridir.
Yazıdaki amacım aslında günlük hayatta yaptığımız çok basit kod yazım hatalarına yer vermek. Konuyla ilgili birkaç maddeyi aşağıda sıralıyorum. Başlamadan önce vurgulamak istediğim bir nokta var; aşağıda bahsettiğim durumlar sıklıkla karşılan konular ve düzeltilmesi gerçekten çok kolay ve basit durumlar. Sadece bu maddelere dahi dikkat etsek yazdığımız kodda ciddi bir kalite artışı olabilir.
1. Anlaşılması zor isimlendirmeler kullanmaktan kaçının. İsim kısaltmaları veya genel isimler(arr, str, no, id… gibi) kullanmayın. Sadece değişkenlere verilen isimler değil, metot ve sınıflara verilecek isimleri de iyi seçmek gerekiyor. Aşağıda bu tarz kullanımlara hatalı ve doğru örnekleri bulabilirsiniz.
string cstName; int id; int[] arr = new int[5]; bool change;
string customerName; int cityId; int[] luckyNumbers = new int[5]; bool isChanged;
2. Değişebilecek değerleri kod içerisine gömmeyin. Örneğin veritabanı bağlantı cümlesi veya bir sayfada gösterilecek kayıt sayısı… gibi değerleri kod içerisinde saklamak ileride bu bilgileri değiştirme ihtiyacı çıktığında kod değişikliği yapılmasına, zincirleme olarak da canlı ortamdaki uygulamanızı deploy etmenize yol açar. Bu bilgileri XML vb. bir dosyada saklayarak uygulama içerisinden okunması daha doğru bir yöntemdir.
string connectionString = "data source=ServerAddress; initial catalog=DbName; user id=Username; password=myPassword;" int rowCount = 20;
string connectionString = Config.Get("ConnectionString"); int rowCount = Convert.ToInt32(Config.Get("RowCount"));
settings.xml
<settings> <add name="ConnectionString" value="data source=ServerAddress; initial catalog=DbName; user id=Username; password=myPassword;" /> <add name="RowCount" value="20" /> </settings>
3. Gün, ay, renk, kullanıcı tipi gibi sabit değerler için string veya integer değişkenler yerine enum sabitlerini kullanın.
if(day == "Pazartesi") { } else if(day == "Salı") { }
if(day == Day.Pazartesi) { } else if(day == Day.Sali) { }
...
enum Day { Pazartesi = 1, Sali, Carsamba, Persembe, Cuma, Cumartesi, Pazar }
4. Kullanmayacağınız ve ileride ihtiyaç olmayacak kodları yorum satırı içerisinde saklamayın, doğrudan silin! Bu tarz bloklar gereksiz kod kalabalığına yol açar, kodun okunurluğunu azaltır, kafa karıştırır… Zaten TFS, GIT vb. kod versiyonlama araçlarını kullanıyorsanız eski kodlarınız versiyon geçmişinde duruyor, boşuna yorum satırı olarak bırakıp kod kalabalığı oluşturmayın. Sağdaki resimde klasik “kod içinde unutulmuş yorum bloğu” görebilirsiniz(resime tıklayıp daha büyük haline göz atabilirsiniz).
5. HTML kodu içerisinde zorunlu olmadıkça inline CSS ve Javascript kodu bulundurmayın. Bu tarz kodlar varolan bir .css veya .js dosyasına taşınabilir veya yeni bir dosya açılabilir.
6.HTML kodlarının okunaklılığı açısından basit ama bir o kadar önemli bir konu: Kod satırlarındaki girintilere, kodu satırlara ayırmaya ve satır arası boşluklara dikkat etmeliyiz. Bu aslında teknik bir konu değil, sadece kodun daha iyi okunması için yazdığınız kodlara çeki düzen vermeyle ilgili bir durumdur.
<h1>Sayfa başlığı</h1><p>Kısa açıklama</p> <div><div>Bu kısımda da detaylı içerik olacak. Mesela buraya birer link ve resim ekleyelim: <a href="link.htm">Sayfaya link</a> <br />Bu da resimimiz: <img src="resim.jpg" /></div></div>
<h1>Sayfa başlığı</h1> <p>Kısa açıklama</p> <div> <div> Bu kısımda da detaylı içerik olacak. Mesela buraya birer link ve resim ekleyelim: <a href="link.htm">Sayfaya link</a> <br />Bu da resimimiz: <img src="resim.jpg" /> </div> </div>
7. String birleştirme işlemlerinde + operatörünü kullanmak yerine formatlama seçeneklerini tercih ediniz.
string smsMessage = "Sayın " + customerName + ". Üyelik onay kodunuz: " + verificationCode;
string smsMessage = string.Format("Sayın {0}. Üyelik onay kodunuz: {1}", customerName, verificationCode);
Örnekleri arttırmak mümkün, eminim ki burada bahsi geçen yedi farklı kötü kod örneği sizlere çok tanıdık geliyordur. Yazının başında da bahsettiğim üzere bu tarz kod yazım hataları genellikle dikkatsiz ve acele şekilde iş yapma durumlarında ortaya çıkıyor. Daha bilinçli, dikkatli şekilde kod yazmak ve işimizi çok aceleye getirmemek yazdığımız kodların kalitesini ciddi şekilde arttıracaktır. Bu bilinçle daha temiz ve anlaşılır kodlar yazmamız dileğiyle yazımı sonlandırıyorum.
Aklınıza gelen ve günlük hayatta sıklıkla yapılan basit kötü kod örnekleri varsa yazıya yorum olarak ekleyebilirsiniz.
9 Comments
Eralp
28 Ekim 2015 at 04:45Selam Uğur ,
Seninde bildiğin gibi bu iş için yeterince olgun olan bir çok refactoring tool’u var..(Resharper,CodeRush,JustCode..) Takımda yer alan herkes refactoring etme noktasında belli başlı bazı policy’leri kabul edip ( ki standart templateler bile iş görür.) kodu commit etmeden önce warningleri elimine etmek için az cok caba harcasa olay zaten team bazında bir standardizasyon doğurur ve dolayısıyla bir üst level’a geçmek kolaylaşır..
Resharper bu konuda çok başarılı.
Benim önerim “less string more control”.. Yukarıda verdiğin days enum’i güzel bir örnek..Zaten bünye belli bir süre sonra o şekilde bir kod yapısıyla karşılaşmadığında arıza çıkartmaya başlıyor
Uğur Umutluoğlu
2 Kasım 2015 at 10:03Selam Eralp,
Kesinlikle katılıyorum, bu tip refactor araçları kodun kalitesini bariz şekilde arttırdığı gibi yazılımcıya da yaptığı hataları diğer bir deyişle yazdığı kötü kodları gösteriyor. Eğer bilgisayarlarımızı aşırı yavaşlatmıyorsa bu tip araçları kullanmak gerekir diye düşünüyorum(sıfır hatayla kod yazan guru’lar kullanmayabilir ). Diğer taraftan bu tarz araçları edinemeyen veya kullandığı IDE’de bu tip araç/eklenti olmayan arkadaşlar için faydalı birkaç örnek ile konuya vurgu yapmış olduk biraz.
Levent Yıkılmaz
28 Ekim 2015 at 17:01Paylaşımınız için teşekkür ederim, keyifle okudum.
Victor
28 Ekim 2015 at 20:34Soru yanlış olmuş bence iyi kod nasıl yazılır olmalıydı. Onun da cevabı ‘kod yazmayarak’ olur. Her gün, dünün kodunu refactor etme ihtiyacı hissediyorum.
Uğur Umutluoğlu
2 Kasım 2015 at 09:59Kasıtlı olarak ironik bir başlık seçtim Victor, her yerde zaten “temiz kod” vurgulanıyor. Bu şekilde nasıl “kötü kod” yazdığımızı vurgularım diye düşündüm. Kötü yapmamışımdır umarım
Murat
4 Kasım 2015 at 17:46Güzel bir yazı olmuş hocam. Hepimizin Zaman Zaman atladığı noktalar oluyor dikkat etmek gerekiyor.
Muhammed
10 Kasım 2015 at 20:46Size tavsiyem enum tanımlarken her zaman ilk değerlerini atayın(Yukaridaki ornekte sadece pazartesi icin 1 atanmis)… Çünkü bazen enum tipini db’de integer olarak tutabiliyoruz. Daha sonra yeni bir enum tipi eklenince kaymalara sebep olacaktır. Buna dikkat edin!!!
Caner Eymen
2 Mart 2016 at 12:51Değerli paylaşımınızdan dolayı teşekkür ederim.
Faruk
25 Ağustos 2017 at 11:29String okunurlugu icin interpolation tavsiyemdir.
string smsMessage = $”Sayın {customerName} Üyelik onay kodunuz: {verificationCode};