Temiz Kod

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler

Debug yazısından sonra bu yazıda kodun okunurluğu açısından son derece önemli olan temiz kod konusuna  değinmeye çalışacağım. Temiz Kod’dan kastın ne olduğu, Temiz Kod’un avantajları, temiz kodun nasıl yazılacağı gibi sorulara deneyim ve araştırmalarım neticesinde oluşan bilgilerimi aktarmaya çalışacağım. Çoğu kulağımızın aşina olduğu, bilip de bazen dikkat etmediğimiz pratikleri bu yazıyla not etmiş olacağım. Bu yazıyı yeni öğrendiğim ya da deneyimlediğim tecrübelerim neticesinde sürekli güncellemeye çalışacağım. Bu yazıyı okumaya devam ediyorsanız, muhtemelen bir yazılımcı ya da yazılımcı olmaya niyetli birisiniz. Bu yazının amacı işte daha temiz bir yazılım yapmak, temiz yazılım yapmanın neticesinde daha iyi bir yazılımcı olmak.

Öncelikle temiz kod yazımı bugünden daha fazla geleceğe yatırımdır. Yarın daha fazla zaman harcamamak için kodu yazarken temiz kod için vakit ayrılmalıdır. Temiz kod, prensipleri basit ama biraz vakit alıcı, üzerinde düşünülmesi gereken bir konudur. Temiz kod yazmada temel amaç kodun basit ama verimli, okunulabilir, test edilebilir ve yeni ihtiyaçlara uyarlanabilir olmasıdır. Temiz kod yazmak sizden sonra gelecek yazılımcının kodu anlayabilmesi ya da ileride çıkabilecek herhangi bir problemde kodu anlamada oldukça yardımcı olacaktır. Buradan hareketle sadece çalışan kod yazmak hedef olmamalıdır. Kodu yazmak kadar geliştiricilerin kodu okuyup, anlayıp, yeni ihtiyaçları ve bakımını kolay yapabilecekleri şekilde yazılmasıdır. Kurumsal firmalar, büyük modül ve projelerde bu daha da önemlidir. Bu amaçla bazı firmalar KGG’si yapılmamış, standartlara uygun olmayan kodların üretimine izin vermeyen toollar kullanmaktadırlar.

Kod yazma sürecinde uzmanlaştıkça programın çalışması işin tamamlanması açısından yeterli olmaktan çıkıyor.  Yeni kodlamaya başlayan ,Junior bir geliştirmeci için kodun çalışması yeterliyken; yıllar geçtikçe  kodun doğru bir şekilde çalışmasının yanında performans, kodun okunabilirliği, unit test gibi kavramlar önem kazanmaya başlıyor. Bu iki farklılığı kavramlaştıracak olursak; birisi Programlama iken diğeri İyi Programlama olarak ifade edilebilir. Kodun çalışmasını referans almak günü kurtarabilir ama daha sonra gelen bir hatayı anlama ve çözme ya da yeni bir geliştirmecinin orada çalışma ihtiyacı doğduğunda oldukça problemli bir hal alacaktır.

Yukarıda saydığımız tüm gerekçeler neticesinde temiz kod yazmak bir ek katkı değil zorunluluk haline geliyor. Programlamanın sanat olduğuna inanan birisi olarak Donald Knuth’ın alıntısıyla söylemek istediğimizi daha net ifade edelim.

Programming is the art of telling another human what one wants the computer to do.

Donald Knuth

Kodun da bir eser olduğunu düşünüyorum. Ve bu eserin başkalarına bir şeyler ifade etmesi eseri daha da kıymetli hale getirir.

Bu kadar  Temiz Kod Dedikten sonra temiz kodun özellikleri nelerdir onları sıralayalım :

  1. Okunması kolay olmalı. Okurken kod parçaları arasında kaybolmayıp, bir parçanın bütünün keşfeder gibi okunmalı
  2. Net olmalı. Her bir sınıf, entity, business katmanı ya da metod sadece bir amaca hizmet etmeli.
  3. Bakımı yapılabilir olmalıdır. Bakımı yazımından daha zor olacak kodlardan kaçınmalıyız :)
  4. Tüm testlerin başarılı bir şekilde tamamlaması
  5. Tekrar (duplicate ) olmaması
  6. Kullanılmayan kodların olmaması.

Kodumuzu bu maddelere uygun yazıp sonuçlandırdık. Peki bu şekilde  Temiz Kod yazmanın bize avantajları ne olacak diyecek olursak;

Temiz kod’un avantajları

  1. Kod parçalarının amacının ne olduğunu anlamayı kolaylaştırır.
  2. Uygulamanın akışını kolaylaştırır
  3. Farklı objelerin birbiriyle nasıl çalıştığını anlamayı kolaylaştırır
  4. Her class, entity ya da metodun rolünü ve sorumluluğunu anlamayı kolaylaştırır.
  5. Refactor, bugları bulma ve kodu düzenlemede hızlı aksiyon almaya yardımcı olur. Bakımı kolaylaştırır. Zaman kurtarır.
  6. Kodun değiştirilmesini, yeni ihtiyaçları hızlı entegre etmeyi sağlar.
  7. Kodun testini kolaylaştırır. Unit testleri anlama ve yazmada kolaylık sağlar.
  8. Yeni geliştirmeler için efor tahmin etmeyi kolaylaştırır. Beklenmeyen durumlarla karşılaşma olasılığını azaltır.
  9. Kodda sıkılmadan geliştirme yapmanızı sağlar. Temiz olmayan bir kodda geliştirme eziyete dönüşebilir çünkü. Eziyettir. Lemi Orhan’ın ifadesiyle o kod kokmaktadır. Ve kötü kokan bir kodda yazmak istemezsiniz.

Temiz Kod yazmada en önemli hususlardan birisi isimlendirmedir. Doğru yapılmış bir isimlendirme metodu incelemeye gerek bırakmayabilir. Ve bu da vaktinizi size bırakır. İsimlendirme oldukça zaman alan bir uğraş. Ancak doğru verilmiş bir isim daha sonra ayıracağınız zamanı size bırakır. Değişken, sınıf ya da fonksiyon ismi onunla ilgili sorulara cevap vermelidir. Neden olduğu, ne olduğu, nasıl kullanıldığını anlatmalıdır. Eğer bu soruların cevaplarını yorum ile yazıyorsanız isimlendirmeniz eksik kalmış demektir.  List gibi genel ifadeler yerine customerCardList gibi daha net ifadeler kullanılmalı. Önek ya da altçizgi gibi ifadeler kullanılmamalıdır. Şimdi sırayla değişken, sınıf, metod isimlendirmelerini ele alacağız.

Değişken İsimleri :  Anlamlı, aranabiliyor olmaları kolay bulunması açısından  önemlidir. (startDt yazmak yerine startDate). Açık, anlaşılır olması teknik bir ifade olmasından iyidir. Değişkeni tanımladığınız sınıf ya da obje isminde kullanılan bir ifadeyi değişken adında tekrarlamaktan kaçınılmalıdır. GetCustomer metodunda müşteri bilgisi atanan bir değişkeni Customer öneki eklemek fazlalık olacaktır.  Bazı metod değişkenlerinin default atamaları vardır. Değişken default atamaları  parantez içerisinde değişken yazılırken atamasını yapılmalıdır.

Sınıf İsimleri: Sınıf isimleri isim veya isim türevli ifadeler olmalıdır. Genel ifadelerden kullanmak yerine sınıfı ifade eden isimlendirmeler yapılmalıdır. Sınıf ismi sıınf içerisindeki metodların üst başlığı gibi görülmelidir.

Metod isimleri : Metod isimlerinin bir fiil ile başlaması daha doğru olacaktır. GetCustomer,DeleteCustomer,SaveCustomer, CreateCustomer gibi. Metod ismi metodun işlevini net olarak ifade etmelidir. İsimlendirme son derece kibar veya sert olmalıdır. (Üniversite birinci sınıf BMG dersi kodlama sınavında nasıl nazik bir sonuç yazdırdığımı hatırlayan arkadaşlar bunu daha iyi anlayacaklardır. Zira halen gülme konusu olur bu nazik uyarım :))

Metodlar : Fonksiyonlar öncelikle tek bir amaca hizmet etmelidir. İkinci olarak metodlar kısa olmalıdır.  Max sınır olarak tüm metodun ekranda tek seferde görüntülenmesi gibi bir varsayım konulsa da mümkün olduğu kadar kısa, okunabilir ve amaca hizmet etmelidir.  Metodlar ile ilgili yorum yazmaktan kaçınılmalıdır. Gerçekten yazılması zorunluysa yorum yazılmalı.  Eskiden metod üzerine vs’nin default verdiği syntax ile yorum yazmanın faydalı olduğunu düşünürdüm ve uygulardım. Ancak zamanla kodun kendisini anlatması gerektiğini düşünmeye başladım. Metodlar ile ilgili yorumlar sadece business bilgisi ya da bilinmeyecek bir yazılım kullanımı yapılmışsa yazılmalı.  Aksi takdirde KOD KENDİSİNİ ANLATABİLMELİ.

Metod içerisinde koşul ifadeleri ile de birkaç cümle yazarak metod kısmını da tamamlayalım. Bazen if, switch koşullarında oldukça uzun kontroller yapılıyor. Satırlar süren, or ve and keyleri ile zincire dönen koşulları bir if() parantezine sığdırmak kodu okunur olmaktan çıkarıyor. Bu durumlarda koşulları yeni bir metod yapıp buradan çağırmak hem okuma hem anlama açısından daha sağlıklı olacaktır.

Metod değişkenlerinin sayısı : Bunun için 2 diyeni de duydum, üç diyeni de, dört diyeni de duydum. Dörtten fazla alabilir diyeni duymadım ama gözlerim üç dört satır değişken alan fonksiyon gördü J  Bir fonksiyon üçten fazla değişken almamalı. Bu sayı mümkün olan minimum sayıda tutulmalı. Eğer üçten fazla değişken bekleniyorsa da değişkenleri barındıran bir obje tanımlanıp oluşturulan obje tipinde bir değişken gönderilmelidir.

Temiz kod açısından yazılım bileşenlerinin isimlendirmelerine tek tek değindik. Şimdi de OOP açısından da önemli olan SOLID’ten kısaca bahsedelim.  SOLID,  OOP projelerinin standartları olarak bilinir. Kendisini oluşturan maddelerin baş hraflerinden oluşur:

S – Single Responsibility Principle (SRP): Her nesnenin sadece bir sorumluluğu olmalı, tek bir amacı olmalıdır. Herhangi bir değişiklik yapıldığında bu nesnenin amaç ya da sorumluluğunun değişmesinden dolayı olmalıdır.

O – Open/Closed Principle (OCP): Yukarıda belirtmiştik.; Metod düzenlemelere, yeni şart ve güncellemelere açıktır. Ancak metod ya da nesnesin varlık sebebini etkileyecek değişiklikler yapılmamalıdır.

L – Liskov ‘s Substitution Principle (LSP): Türetilen bir nesnenin türetildiği sınıfın metodlarını kullanmasıdır.

I – Interface Segregation Principle (ISP): Nesnelerin ihtiyaç duymadıkları Interface’ten ayrılması ilkesidir.

D – Dependency Inversion Principle (DIP): Yüksek seviyeli sınıfların daha düşük seviyeli metodlara bağımlılığının olmamasıdır. Alt sınıflardaki değişiklikler üst sınıfları etkilememilidir.

Toparlayacak olursak ; Temiz kod kodun kaliteli olması açısından önemli ve vakit ayrılması gereken bir aşamadır. Tabi bunu söylerken çok temiz kod yazacağım diye aşırı titiz davranmak da gerekmez. Temiz kod yazımı dikkat edilmesi durumunda zamanla gelişecek bir çalışma. İlk denemede olmayabilir, dolayısıyla üzerinde çalıştığımız kodu geliştirmek için her zaman çaba göstereceğimiz bir zihniyet benimsememiz gerekiyor. Yazılan kodun temiz kod açısından yeterince iyi olduğunda karar verdiğimizde yeni koda devam etmeliyiz.

Kaynaklar:

https://medium.com/mindorks/how-to-write-clean-code-lessons-learnt-from-the-clean-code-robert-c-martin-9ffc7aef870c

https://github.com/ryanmcdermott/clean-code-javascript

https://cvuorinen.net/2014/04/what-is-clean-code-and-why-should-you-care/

Leave a Reply