O kadar zamandır o kadar çok defa kullandım ki, “Happy Path Programcılığı” lafını bir yerden mi duydum, kendim mi uydurdum hatırlamıyorum. Boğaziçi Tarzancası konuşma alışkanlığını her ne kadar yenmeye çalışsam da, tam olmuyor görüleceği üzere. Türkçe olarak, “Mutlu Yol Programcılığı” diyebiliriz buna.
Nedir bu “Mutlu Yol Programcılığı”? (Bundan sonra MYP diyelim adına, bakarsın insanlar kullanır, tutar…)
MYP, kod yazarken, olası hata durumlarından hiçbirinin oluşmayacağını varsayarak, her şeyin mükemmel çalışacağını düşünmek demektir.
Bu bir hastalıktır. Bunun yayılması, işin sonrasında, test ve hata ayıklama aşamalarında işimizi inanılmaz zor bir hale getirir.
Hastalığın semptomları nelerdir?
– Programa, dışarıdan (dosya, kullanıcı, ağ…) üzerinden herhangi bir veri girişi olduğunda, bunun geçerli olup olmadığının denetlenmemesi. Mesela, kullanıcıya sayı girmesini söyledik. Girdiği şeyin gerçekten sayı olup olmadığını kontrol etmedik.
– Hata alabilen bir sistem fonksiyonu veya metodu çağırdığımızda, hata durumunu ciddiye almamak. Özel olarak, exception atan dillerde, atılan exception’ı “öylesine” yakalamak.
– Kütüphane kodu veya o şekilde kullanılacak bir kod parçasında, dış parametrelerin (özel olarak “public” metodların parametreleri) kontrol edilmeden kullanılması.
Mesela, sıklıkla görülen bir örnek:
BufferedReader reader = null;
try {
reader = new BufferedReader(new File(“hede.txt”));
} catch (Exception e) {
}
…
Yazma anını izlerseniz, olay şöyle gelişir: Önce:
BufferedReader reader = new BufferedReader(new File(“hede.txt”));
Yazılır. Sonra, bu satır hata verince, etrafına try-catch konur. Sonra, dışarıda kullanabilmek için reader tanımı dışarı alınır. Sonra oluşan “bunun değeri bazen belirsiz oluyor” hatasından kaçmak için, “= null” kısmı eklenir.
Oldu mu? Evet, mükemmel bir MYP oldu.
Böyle bir kod parçasını görüp de, “yapma bunu böyle” derseniz, önünüze gelecek ilk tepki, “ya ne yapayım”dır. Neyse ki bunun cevabı var!
MYP’nin en kötü tehlikesi, oluşan hata durumu, halının altına süprüldüğü için, programın alakasız bir yerde, alakasız bir hatayla çatlayacak olmasıdır. Sonrasında, hatayı ayıklamak için, “lan bu hata nasıl oluyor da oluyor” diye kodu satır satır didiklemek gerekir. Izdırap.
MYP’den kaçınmak için, bazı prensipleri şöyle sıralayabiliriz:
- Her hatayı, oluştuğu yerde try/catch ile bertaraf etmeye çalışmayın. İlk refleks olarak, try/catch eklemek yerine, metoda “throws” eklemek daha iyi bir tepkidir. Elbette ilk refleksler, durumu doğru anlayıp, doğru şeyi yapmanın yerini tutmaz.
- Eğer bir kütüphane veya yardımcı kod içindeyseniz, ne amaçla kullanılacağı belli olmadığından, oluşan hataları sizi çağıran koda göndermek daha doğru harekettir. Çünkü, oluşan problemi düzeltecek bir eylemi, sizin yapmanız mümkün değildir.
- Eğer, kavramsal olarak bir iş yapan bir kod içindeyseniz, kendinize özel bir exception tanımlamak ve yakaladığınız exception’ları kendi exception objeniz ile sarıp atmak, daha mantıklı olabilir.
- Hata attığınız zaman, hata mesajına olağanüstü önem verin. Olağanüstü derken, şaka yapmıyorum. Hata mesajını okuyanın, hatanın ne olduğunu anlamak için, kodu açıp bakmasına gerek kalmıyorsa veya debug modunda kodu yeniden çalıştırması gerekmiyorsa, hata mesajınız yeterince iyidir. Yani, mesela hatayla ilgili değişkenlerin değerlerini hata mesajının içine yazmak mantıklı bir harekettir.
- “Eğer bu hata oluşuyorsa, kodlama hatası vardır” dediğiniz durumlarda, (Java yazıyorsanız) RuntimeException (tercihan bir türevini) atın.
- Kodun hata vermesi, kendiliğinden kötü bir şey değildir. Eğer hata verecekseniz, mümkün olan en erken yerde ve en korkunç şekilde verin. (Frenkler buna “fail fast” diyorlar.)
- Bir try/catch’de, catch’in içi asla boş olmamalıdır. Yakalanan hata, en azından loglanmalıdır. Eğer, “bu try/catch formalite, bu hatanın oluşmasına imkan yok” diyorsanız, (ki böyle durumlar vardır — mesela Java’da Charset.forName(“UTF-8”) exception atar gibi görünür, ama atamaz [normal şartlar altında]) o zaman bile bir RuntimeException ile sarmalayıp yakaladığınız exception’ı atın. Tut ki oldu, hep beraber şaşırırız.
- Eğer ilgili hata durumunda, artık herhangi bir kodun çalışmasının bir anlamı kalmadı veya ne yapacağı belirsiz hale geldiyse, o zaman Error atmak caizdir. (Bunu normal exception tutan şeyler tutmaz. Program muhtemelen ölür.) Mesela JVM’in attığı OutOfMemoryError bir error’dur… Yaratmaya çalıştığınız obje yaratılmayınca kimbilir ne olur?
İşin gerçeği şu ki, MYP ile yazacağınız kod miktarı, tüm hata durumlarını doğru şekilde ele aldığınız durumda yazacağınız kod miktarının yarısından azdır. Ancak, MYP ile hata ayıklamada harcayacağınız süre, düzgün hata ele alımıyla yazılımış kodun iki katından kesin fazla, benim kestirimime göre en azından dört katı olacaktır.
Kendinize ve takım arkadaşlarınıza acı çektirmeyin.
Hataları halının altına süpürmeyin.
Yapmaaaayıııııın öyleeeeeee!!!!
Gökmen Görgen der ki
For döngüsü içinde try – except kullanıp, exceptionları continue ile pas geçmek caiz midir hocam?