Yazılımda Temiz Kod (Clean Code) Üzerine – Bölüm 1
Ne yazık ki yazılımcıların deneyimli ve zeki olmaları, temiz kod yazacakları anlamına gelmiyor. Bir yazılımın çalışıyor olması, tüm fonksiyonlarının doğru sonuçlar vermesi de yeterli değildir. Eğer sadece bu unsurlar yeterli olsaydı, yazılım projeleri hiç gecikmeden ve sorunsuz bir şekilde tamamlanırdı. Projelerin özellikle sonlarına doğru yaşanan problemler ve gerginlikler minimum düzeyde yaşanırdı diyebiliriz. Bu yazı dizimizde asıl hedefimiz, temiz kod prensipleri ile kaliteli, performans odaklı ve zamanında tamamlanan projelerle tüm paydaşları — yazılımcıları, müşterileri ve kullanıcıları — mutlu etmenin yollarını arayacağız. Bu memnuniyetin anahtarlarından birinin, hatta en önemlisinin temiz kod prensiplerine uygun yazılım geliştirmekten geçtiğine inanıyorum.
Kirli veya “kokan” kod ise tam tersine, bakımı ve geliştirilmesi zor, paylaşılması veya devredilmesi güç, genişlemesi ve bakımı problemli bir yapıya sahiptir. Bu tür kodlar, üzerinde çalışanları yoracağı gibi, enerjilerini de tüketir. Dolayısıyla, temiz kod yazmak sadece teknik bir detay değil, projenin genel başarısı ve tüm paydaşlar için kritik bir unsurdur.
Aslında, kodun basit ve anlaşılır olması, daha büyük bir çabayı gerektirir. Temiz kodlama için belirli prensipleri öğrenmek ve disiplinli bir şekilde uygulamak gerekir. Burada, global anlamda alanında uzman kişilerin prensiplerine dikkatle kulak vermek ve bu prensipleri benimsemek önem taşır. Hedefimiz hatasızlık veya mükemmellik değil, herkes için faydalı olacak bir metodolojiyi uygulayarak ortaya nihai anlamda yine bizler gibi insanların kullanacağı başarılı uygulamalar geliştirmektir.
Gözle görülmeyen bazı gerçeklere değinmeden geçmeyelim, günümüzde ne yazık ki hemen her konuda rekabete, yarışa dayalı bir alt yapıdan geliyoruz. Bu durum (tırnak içinde) ‘beyaz yaka’ ya fazlasıyla sirayet etmiş durumdadır ve gözle görülmeyen rekabet ortamları olabilmektedir. Böylesi ortamlar beraberinde egosantrik diye isimlendirebileceğimiz, belki kaba bir tabir olacak ama kendilerini ve işlerini hep ön planda, merkezde gören, farkında olarak veya olmadan bencil, ‘dediğim dedik çaldığım düdük’ yazılımcıların ortaya çıkmasına zemin hazırlamaktadır.
Girizgahtan sonra temiz kodun (clean code) neden çok önemli olduğuna ve anlaşılır kod yazmanın kritikliğine dair çok az daha kelamda bulunmama müsaade edin. Çünkü temiz kod ile nihai ürün çıktıları tüm paydaşları kapsayacak şekilde büyümesi olanaklı, devredilmesi ve paylaşımı rahat, değişimi ve bakımı kolay, maddi ve mesleki tatmin getirisi de cabası olacaktır. Elbette tüm bunlar için iyi niyetli bir tutuma sahip olmak ön koşuldur diyebiliriz. Kişisel tutumlarımızı bir kenara bırakarak, ekipteki en yeni üyeden tutunda, projeye tüm dokunan tarafların fayda göreceği bir tutum ve iyi niyet içerisinde olunması gerekmektedir. Dolayısıyla yazılım veya kodlama uğraşı yalnızca doğru çıktılar vermek üzerine tasarlanmamalıdır diyebiliriz.
Girişi biraz uzun tuttum; ancak konunun önemini vurgulamanın en az prensipler kadar önemli olduğunu düşünüyorum. Şimdi, Amerika’yı yeniden keşfetmeden, temiz kod yazma prensiplerine geçelim. Robert C. Martin’in önerilerini, tüm yalınlığıyla ele almaya çalışacağız.
İlgilenen arkadaşlar buradan temel prensiplerin bir özetine erişebilirler.
Robert Martin’e göre; “kod, ekipteki herkes tarafından kolayca anlaşılabiliyorsa temizdir. Temiz kod, kodu ilk geliştirenden başka bir geliştirici tarafından okunabilir ve geliştirilebilir olmalıdır. Çok rahatça anlaşılabilir olmasının yanı sıra, kod okunabilir, değiştirilebilir, genişletilebilir ve sürdürülebilir olmalıdır.”
Bu alıntı üzerinden şu noktayı tekrar vurgulamak istiyorum: Eğer objeye-dayalı bir programlama dili kullanıyorsak, (ki büyük çoğunluğumuz böyle) kullandığımız programlama dilinin objeye-dayalılık ilkelerini uygularken, anlaşılırlık veya temiz kod ilkelerine göre yazmanın ön bir koşul olması gerekliliğidir. Robert Martin’in de belirttiği gibi, yazdığımız kodlar, takıma yeni katılan bir üyenin bile kolaylıkla anlayabileceği şekilde olmalıdır. Görünen şu ki, şirketlerin kalite departmanları genişlemekte, (code reviwer) kod gözden geçiricilere daha fazla ihtiyaç duyulmakta, hatta IDE’ler dahi daha akıllı duruma getirilmeye çalışılmaktadır.
Artık sözü Martin’e bırakalım ve genel kurallara geçerek temiz kodu prensiplerine göz gezdirmeye başlayalım.
Genel temiz kod kuralları:
- Standart kodlama kuralları. Buradan şunu anlayabiliriz, genel olarak kabul gören kodlama prensiplerini takip etmeliyiz. İsimlendirmeler ve kod ilk görünüşte dahi herkes tarafından anlaşılır olmalıdır.
- Anlatmak istediklerini en aptal insanın anlayabileceği basitlikte tutun. Karmaşıklığı mümkün olduğunca azaltın. Orijinali burada: Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible.
- İzci kuralı. Kamp alanını bulduğunuzdan daha temiz bırak. Daha temiz bırak burada önemli.
- Her zaman en temelde yazılmak istenene odaklanın. Yani problemin çözümünde asıl hedeflenen nedir? Doğru yerde mi? Olması gerekiyor mu? gibi soruları kodumuzu yazdıktan sonra da kendimize sorabiliriz.
Kodun kokması (Code smells):
Yazılan kodlar kokar mı demeyin, hem de fena kokar. İyi bir tabir kullanılmış Martin tarafından. Eğer burnunuza koda dair kötü kokular geliyorsa ortada problem var demektir ve çözülmelidir.
- Sertlik/sağlamlık. (Kod aşırı küçük bir değişiklikten sonra ardı ardına gelen değişikliklere neden olmamalıdır.)
- Kırılganlık. (Tek bir değişiklikte dahi yazılım birçok yerde bozulmamalıdır.)
- Hareketsizlik. İlgili riskler ve yoğun çaba gereksinimi nedeniyle kodun bazı kısımlarını başka projelerde yeniden kullanamazsınız.
- Gereksiz Karmaşıklık. (Baştan doğru kurgulamanın, düşünerek yazmanın önemi olarak yorumlayabiliriz.)
- Gereksiz Tekrar. (Bakım ve değişimde problem yaşamamak için, tekrara düşmeden kodu merkezinden yönetin.)
- Anlaşılması zor. (Yazımızın ana odak maddesi. Yalın ve mümkün olduğunda sade)
Fonksiyon/Metot kuralları:
- Küçük. (Fonksiyonlarınız mümkün olduğunca küçük olmalıdır. Uzuyorsa kokmaya başlar.)
- Bir tek şey yapın. (Fonksiyonunuz asıl işini yapmalıdır, fonksiyon yalnızca kendi işine odaklı olup, gereksiz kodlar serpiştirmeye başlarsanız, kodunuz kokmaya başlar.)
- Tanımlayıcı isimler kullanın. (Ekipteki herkesin anlaması önemli, hatta ileride siz de anlayın.)
- Daha az parametre tercih edin. (Mümkün olduğunca daha az parametre ile ileride yazdığınız metodun başka yazılımcılar veya metotlar tarafından da çağrılabilir/kullanılabilir olacağını unutmayın)
- Yan etki olmamalıdır. (Fonksiyonunuz, ismi, parametreleri ile uyumlu output dönmelidir.)
- Bayrak parametre kullanmayın. Fonksiyonunuzu, istemciden bayrak olmadan çağrılabilecek birkaç bağımsız yönteme bölün. (Martin burada, fonksiyonunuz mümkün olduğunca yalın olsun, gereksiz yere bir flag/bayrak/işaretçi kullanmayın demek istiyor. Örneğin fonksiyonunuza bool (true veya false)bir parametre göndererek, metot içerisinde true ise böyle çalış, false ise şöyle çalış şeklinde yazmaktansa, bu fonksiyonu bölerek true için ayrı, false için de ayrı bir fonksiyon veya metot kullanarak sade şekilde yazınız demek istemektedir. Aksi durumda kodunuz kokmaya başlayacaktır.)
Anlaşılabilirlik için ipuçları:
- Tutarlı olun. Bir şeyi belirli bir yol ile yapıyorsanız benzer şeylerin tümünü aynı şekilde yapın.
- Açıklayıcı değişkenler kullanın. Değişken isimleri işlevini açıkça belirtmeli, neye yaradıkları anlaşılmalıdır.
- Yapacağınız işlerin sınır şartlarını belirtin. Sınırlı koşulları takip etmesi zor olabilir. Bunların işlemlerini ayırın. (Örneğin bir fonksiyonunuz integer parametre alıyorsa ve bu parametre metot içerisinde bir Array’de kullanılacak ise, Array’in sınırlarına göre parametre gönderilip gönderilmediğini ayrı bir method ile gerçekleştirebilirsiniz.)
- İlkel veri tipleri yerine özelleştirilmiş nesneleri tercih edin. Veri taşıyan basit tipler yerine, bu verileri taşıyacak özel sınıflar oluşturun.
- Mantıksal bağımlılıklardan kaçının. (Bir sınıf veya metot adıyla-sanıyla yalnızca kendisinin yapması gereken işleri yapmalıdır. Örneğin Personel isimli bir sınıf içerisinde, bu personelin uygulamayı kullanmaya da yetkisi var mı gibi mantıksal bağımlılıklar eklemeyiniz. Aksi durumda kodlar kokmaya başlarlar, yönetimi ve bakımı tahmin edilemeyecek seviyelerde zorlaşmaya başlar.
- Olumsuz koşullardan kaçının. Koşullu ifadelerde olumsuz durumları kontrol etmek yerine, olumlu durumları kontrol edecek şekilde yazın.
Yazımızın bu ilk bölümünde temiz kodun anlaşılması ve önemini vurgulamaya çalışarak, Robert Martin’in belirlemeye çalıştığı prensipleri de açıklamaya çalıştık. Yazımızın ikinci bölümünde yine prensiplere devam ederek kod uygulama örnekleri ile detaylandırmayı planlıyorum…
Gökhan Manduz
Senior Software Engineer & Solution Architect
[email protected]
Referanslar
- https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988cf8d29
- Clean Code: A Handbook of Agile Software Craftsmanship
Eline sağlık.