Clean Code (Temiz Kod)

Sedat Korkmaz
10 min readApr 21, 2021

--

Temiz Kod Nedir?

Temiz kodun aslında belirli bir tanımı yoktur. Tanımı kişiden kişiye değişebilir. Genel bir tanım yapmak gerekirse temiz kod, herhangi bir kişinin kodunuza bakıp kodu okuyup kolayca anlayabildiği, onun üstünde ekleme/çıkarma yapıp güncelleştirebildiği bir koddur.

Peki bir kodun temiz olabilmesi için başlıca kurallar nelerdir?

  • Bir kodun temiz olabilmesi için bence en önemli faktör basit olmasıdır. Basit ve karmaşıklıktan uzak bir kodu anlaması, anlatması ve üstünde çalışması kolaydır.
  • Bir kodu yazarken belli bir standartları gözetmeliyiz. Bu standartlar şirkete göre veya kişiden kişiye değişebilir. Kodu yazmaya başlamadan önce yazılacak kod için bir standart belirlenmelidir.
  • Daima temel nedeni bulmalıyız. Bir problemi çözerken önce temel nedenini araştırmalı ve olabilecek en basit çözümü üretmeliyiz.
  • Üstünde çalıştığımız kodu ortak çalışma alanı gibi düşünmeliyiz. Ortak çalışma alanımızı daima bir sonraki kullanıcı için temiz tutmalıyız.

Tabi ki bu saydıklarım en temel kurallardı. Bunun gibi belki de yüzlerce kural sayılabilir.

Neden kötü kod yazarız?

Bunun için birçok neden sayabiliriz. Bu nedenlerden en yaygın olanı zaman sıkıntısıdır fakat bu bir neden midir yoksa bir bahane midir bilinmez. Projeyi yetiştirmek için kodu hızlı ve özensiz yazmak projeye daha çok zarar verecektir. Halbuki kodu temiz bir şekilde yazmak gelecekte oluşacak zaman kaybını telafi edecek ve çalışanların verimliliğini arttıracaktır. Kötü koda sebep olan en önemli nedenlerden biri de bence kodumuzu hızlı bir şekilde yazıp sonrasında temize dökeceğimizi söylemektir. Çoğumuz kendisi veya bir arkadaşından bunu duymuştur. Peki ya sonrasında kod temize dökülmüş müdür? Çoğunlukla hayır.

Neden Temiz Koda ihtiyacımız var?

Aslında birçok nedeni var fakat bunlardan en basit nedeni yaptığımız işin devamlılığını ve verimliliğini korumak için. Bu konuda Robet Cecil Martin’in Clean Code A Handbook of Agile Software Craftsmanship kitabındaki bir hikâyeden örnek vermek istiyorum.

“80’lerde bir şirket müthiş ve çok popüler bir uygulama yazdı. Ancak bir zaman sonra yeni sürüm çıkma dönemleri uzamaya başladı. Bir sonraki sürümde hatalar çözülmemiş oluyordu. Yüklenme süresi uzuyor ve çökmeler artıyordu. Büyük bir hüsran ile uygulamayı kaldırdığım günü hatırlıyorum. Zaten bir zaman sonra da şirket tamamen piyasadan çekildi.

20 yıl sonra şirketin ilk çalışanlarından biri ile karşılaştım ve ona ne olduğunu sordum. Cevabı korkularımı doğruladı. Ürünü markete erkenden sürebilmek için çok acele etmiş ve kodda çok büyük bir kargaşaya sebep olmuşlardı. Daha fazla özellik ekledikçe, kod daha da kötü bir hal almış ve o kadar kötü hale gelmişti ki, artık kodu yönetemiyorlardı. Böylece kötü kod şirketin kapanmasına sebep olmuştu.”

Bu hikâyeden çıkarabileceğimiz ders kötü ve özensiz kod yazmanın görünenden çok daha büyük sonuçlara yol açabileceğini hatta şirketleri batırabileceğini anlamaktır.

İsimlendirme

İsimlendirme temiz kod için oldukça önemlidir. Kod yazarken değişkenlerde, fonksiyonlarda, nesnelerde ve sınıflarda oldukça fazla isimlendirme kullanıyoruz. Bu yüzden isimlendirmelerin anlamlı, seçilebilir, aranabilir ve anlaşılır olması kodun okunabilirliği açısından çok önemlidir. Peki iyi bir isimlendirme nasıl yapılır? Gelin birlikte bu konuyu belirli başlıklar altında örneklerle inceleyelim.

Anlamlı ve net isimler seçin

Değişkenlerimize, fonksiyonlarımıza vb. yapılara isim verirken ne olduğunu ne yaptığını nasıl kullanıldığını belirten isimler vermeliyiz.

Bu şekilde değişken isimlerine bakarak hiçbir şey anlaşılmıyor değil mi? Peki ya şöyle yazsak:

Bu şekilde çok daha anlaşılır ve anlamlı bir isimlendirme yapmış oluruz.

Değişkenleri isimlendirirken farklı olması için harf çıkarma, yanına sayı ekleme gibi şeyler yaparız ama bu çoğu zaman doğru bir kullanım değildir.

Yukarıdaki örnekte “a1, a2” yerine “Agırlık, BoyUzunlugu” gibi isimlendirmeler daha anlamlı olacaktır.

Kodun içerisinde hiçbir anlam ifade etmeyen sayı kullanmamalıyız. Mesela yukarıdaki resimde yas>=18 koşulu bize yaşın 18’e büyük eşit olması durumunu net bir şekilde anlatıyor fakat 18’in neyin sayısı olduğu hakkında bir fikrimiz yok.

Kodda yaptığımız ufak bir değişikle 18 sayısının ne olduğu hakkında okuyucuya fikir verebiliriz.

Okunabilir isimler kullanın

Verdiğiniz isimlerin okunabilir olmasına dikkat edin. Örnek olarak:

Burada ilk fotoğrafa baktığımızda genymdhms (Generation date, year, month, day, hour, minute and second) adlı değişkeni okumaya çalışalım. Okuması ve anlaması zor bir değişken değil mi? İkinci fotoğrafa baktığımızda ise ilk fotoğraftaki değişkenlere kıyasla hem okuması hem de anlaması kolaydır.

Yukarıdaki örnek de kötü isim kullanımlarından biridir. İsimlendirme yaparken küçük “L” yani l veya büyük “o” kullanmak okuyan kişinin kafasını karıştırabilir çünkü görünümleri bir ve sıfıra benzerdir.

İsimlerde yanlış bilgilendirmeden kaçının

Bir başka örnek vermek gerekirse hesapları tuttuğunuz bir diziye “HesapListesi” şeklinde bir isimlendirme yapmak yanlış anlaşılabilir çünkü hesapları tuttuğumuz şey bir liste değil bir dizidir. “HesapListesi” gibi adlandırmak yerine “Hesaplar” şeklinde adlandırmak daha doğru olacaktır.

Anlamlı bir ayrım yapın

Aynı kapsamda iki farklı değişken vb. yapı varsa, rastgele bir şekilde içlerinden birinin adını değiştirme eğiliminde olabilirsiniz. Örneğin;

Bu iki fonksiyonu okurken aralarındaki farkı anlamak bir hayli zor değil mi?

Burada da üç farklı fonksiyon görüyoruz fakat bu fonksiyonların farkı ne?

Bu iki struct’ın farkı ne?

Yukarıdaki örnekler gibi isimlendirmeler anlamlı bir ayrım yapılmadığı için birbirleri arasındaki farkı anlamak zorlaşıyor. Bu nedenle isimlendirmede anlamlı bir ayrım yapmaya önem vermeliyiz.

Her kavram için tek bir kelime seçin

Örneğin bir şeyin değerini döndürmek için DegerGetir() kullanıyorsanız, kodun geri kalanında aynı kavramı kullanmaya önem gösterin, tüm kodda DegerGetir() yerine DegerAl(), DegerDondur() kullanmak okuyucunun kafasını karıştıracaktır.

Fonksiyon/Metot isimlendirmeleri

Fonksiyon/Metot isimleri işlevi gereği fiil olmalıdır. Örneğin; “KayitliKullanıcılarıGetir(), DokumanıCıkar()” gibi. Bu şekilde fonksiyonun ismine bakarak fonksiyonun ne yaptığını anlayabiliriz.

Sınıf isimlendirmeleri

Sınıf adı, bir isim veya isim cümlesi olmalıdır. Tasarım gereği, sınıflar aynı tür metotları ve değişkenlerin bir birleşimidir, bu nedenle ortak bir ada sahip olmaları gerekir. Sınıflar hiçbir şekilde fiil olmamalıdır.

Komik isimlendirme yapmayın

İsimlendirme yaparken örneğin; YokEdici(), Bomba(), KutsalElBombasi() gibi isimler kullanmak yerine VerileriSil() ismini kullanmak daha açıklayıcı olacaktır.

Aranabilir isimler kullanın

İsimlendirme yaparken kod içinde aranabilir olmasına dikkat etmeliyiz, harf kullanımından kaçınmalıyız (döngülerde kullanılan i,j vb. harfler hariç bunların kullanılmasında sakınca yoktur.).

Koşullar

Koşulların kullanımı hakkında birkaç genel kurar vermek gerekirse bunlar;

  • Koşullu ifadeleri düz ve anlaşılması kolay tutmalıyız.
  • Gereksiz koşul ifadeleri kullanımından kaçınmalıyız.
  • İç içe koşul kullanımı kodu karmaşıklaştırır ve anlaması, okuması zor bir hale getirir. Bu nedenle İç içe koşul kullanımdan mümkün olduğunca kaçınmalıyız.

Bunlar koşulların kullanımı hakkındaki en temel kurallardı. Şimdi gelin başlıklar altında koşulların kullanımını inceleyelim.

Boolean değer kullanımı

Boolean değeri koşul içinde true veya false eşitlemek gereksiz karmaşıklık yaratacaktır onun yerine aşağıdaki kullanım daha doğru olacaktır.

Bazı durumlarda if else kullanmak kodu gereksiz büyütebilir. Aşağıdaki örneğe bakalım.

Bu kod anlaşılıyor ama gereksiz uzun bu kodu aslında tek satırda da yazabiliriz.

Boolean’a direk atama yaparak aynı işlevi gören bir kodu bir satırda yazıp daha kısa anlaşılır bir hale getirmek mümkün.

Yukarıdaki örnekteki gibi karmaşık koşullarda, koşulun takip edilmesi ve ne amaçla oraya konulduğunu anlamak oldukça zordur. Bu durumlarda aşağıdaki gibi boolean operatörlerinde kısa-devre mantığını kullanmak kodu daha anlaşılabilir kılacaktır.

Argüman sırası

Bu iki koda bakalım hangisini okuması daha kolay? İnsanlar çoğunlukla 2.sinin daha okunabilir olduğunu söyleyecektir bunun nedeni günlük hayatımızda kurduğumuz cümlelerde “yaşım 18” deriz “18 benim yaşım” demek anlaması zor ve garip bir cümle olurdu.

Ters koşul ve if/else sırası

Bu iki koddan ilk koda baktığımızda çoğumuz ünlem işaretini görmezden gelip pozitif durumu ele alırdık. Bu durum kodun yanlış anlaşılmasına sebep olurdu. Bu yüzden koşul kurarken if/else sırasında önce pozitif durumu ele almak kodun okunabilirliğini arttırıp yanlış anlaşılmaları ortadan kaldıracaktır.

İç içe if kullanımı

Doğrulama yaparken derin bir şekilde iç içe geçmiş kodun anlaşılması oldukça zordur.

İlk koddaki gibi bir doğrulama zincirinin anlaşılması zordur. Gittikçe karmaşıklaşır. Hangi else’in hangi if ‘e geldiğini karıştırabiliriz. Bunun yerine 2. koddaki gibi her bir doğrulama için if oluşturup return etmek daha anlaşılır olacaktır.

Üçlü (Ternary) operatörü kullanımı

Üçlü operatör koşul yazımını daha kısa hale getirmemize yarar. Bazı durumlarda kodun anlaşılmasını kolaylaştırır. Aşağıdaki örnekte olduğu gibi.

Ama daha karmaşık koşullarda üçlü operatörün kullanımı kodu anlaşılamaz ve karmaşık hale getirebilir bu yüzden bu operatörün kullanımına dikkat etmeliyiz.

Döngüler

Döngüleri kod yazarken mutlaka kullanırız fakat iç içe döngüler ve döngülerin yanlış kullanımı kodu okunamaz bir hale getirebileceğinden dolayı döngüleri kullanırken dikkatli olmalıyız.

Do/while

Birçok dilde do/while döngüsü mevcuttur fakat önce kodun çalıştırılması sonra koşulun kontrol edilmesi birçok kişinin kafasını karıştırabilir. Bu karışıklığı önlemek için do/while yerine while döngüsü kullanmaya öncelik vermeliyiz.

While yerine for kullanın

Bazı durumlarda while yerine for kullanmanız kodun okunabilirliğini arttıracaktır. Bir örnekle açıklamak gerekirse aşağıdaki koda baktığımızda bir i değişkenini sayaç olarak tanımlıyoruz. İki loopta aynı işi yapıyor fakat burada for döngüsü kullanarak kodu daha kısa ve daha açık görüyoruz. Bunu nedeni for döngüsünde i değişkenini tanımlayıp koşul oluşturup arttırma işlemini tek satırda oluşturup görebilmemizdir ve while’a kıyasla i değişkeni for döngüsünde daha yönetilebilirdir.

Tekrarlayan durumlar

Eğer elinizde ikiden fazla tekrarlayan bir durum varsa kısa olduğunu düşünseniz bile aşağıdaki örnekteki gibi loop kullanmanız kodu daha temiz hale getirecektir.

Fonksiyonlar

Fonksiyon yazarken dikkat etmemiz gereken temel birkaç kural vardır. Bunlar;

  • Küçük olmaları
  • Bir tek iş yapmaları
  • İsimlerinin yaptığı işi net bir şekilde belirtmesi
  • Parametre sayısının olabildiğince az tutulması

Küçük fonksiyonlar

Fonksiyonları yazarken dikkat etmemiz gereken en önemli özelliklerden biridir. Bir fonksiyonu yazarken olabildiğince küçük tutmaya çalışmalısınız. Fonksiyonunuzu en fazla 150 karakter ve 20 satırdan oluşacak şekilde yazarsanız kodunuzdaki fonksiyonlar okunması daha kolay bir hal alacaktır.

Tek işlev

Her fonksiyon tek bir iş gerçekleştirmeli ve bunu olabildiğince iyi gerçekleştirmelidir. Fonksiyonun birden fazla iş gerçekleştirmesi kodu karmaşıklaştırıp takip edilmesi zor hale getirecektir.

Net isimler

Fonksiyona baktığımızda isminden ne yaptığını anlamalıyız. Bunu göze alarak fonksiyonlarımızı isimlendirmeli ve bunu yaparken de birbirleri arasındaki farkı da net bir şekilde belirtmeliyiz.

Az parametre

Fonksiyonlara olabildiğince az parametre tanımlamak (0–2) kullanılmasını kolaylaştıracaktır. Eğer fonksiyonlarınızda çok fazla parametre varsa o fonksiyon tek bir iş yapmıyor olabilir. Bu durumda gözden geçirmekte fayda var.

Yorum Satırları

Üzerinde düşünülmüş iyi bir yorum satırı okuyucu için çok faydalı olabilir fakat gereksiz, kötü kullanılmış bir yorum satırı kodu karıştırır okunması zor hale getirir. Unutmamamız gereken bir şey en temiz, en anlaşır kod yorum satırına ihtiyaç duymayandır. Yorum satırı çoğunlukla kötü kodu açıklamak veya karmaşık bir durumu açıklamak için kullanılır. Eğer hiç yorum satırı kullanmadan kodunuzu açıklayabilirseniz o koddan temizi yoktur.

Gereksiz yorum satırı

Bu yorum satırları hiçbir şeyi açıklamaz. Kimse neden yazıldığını da bilmez. Örnek vermek gerekirse;

Kendinizi kodda açıklayın

Yorum satırı yazmadan önce anlatmak istediğiniz şeyi kod üzerinde anlatabiliyor musunuz diye kontrol edin. Çoğu zaman değişkenlere anlamlı isimler atayarak bunu yapabilirsiniz ve gereksiz yorum satırlarından kurtulursunuz.

Zombie kod

Zombie kod, kullanılmayan kod satırlarının yorum satırı olarak tutulmasına verilen addır. Zombie kod okuyucu tarafından kafa karışıklığına yol açar bunun sebebi aklına birçok soru takılmasıdır. Bu kod neden burada? neden şu an kullanılmıyor? kim yazdı? acaba ileride kullanılacak mı? Gibi kafa karıştırıcı sorulara neden olur ve kodun okunurluğunu azaltır.

Yasal yorumlar

Kaynak kodu, telif hakkı veya yazarlık gibi durumlarda kaynak kodun başına aşağıdaki gibi bir yorum satırı koymak mantıklı olacaktır.

Örnek

Bu makalede yazılan temel başlıklar doğrultusunda son bir kod daha inceleyelim.

Bu koda baktığımızda başlıklar altında incelediğimiz örneklerin birkaçının birleşimini görüyoruz. İlk bakışta anlaşılması o kadar da zor gelmeyebilir ama aslında bu kod, temiz kod ilkelerine çok uzaktır. Peki bu kodu nasıl düzeltiriz. Makaledeki bulunan başlıklar doğrultusunda bu kodu düzeltelim.

Kodun ne yaptığını anlayalım

Öncelikle kodun ne yaptığını ve ne anlatmak istediğini anlayalım. Bu duruma göre değişken isimlerini değiştirelim. Bu kod kullanıcıdan alınan bir sayının faktöriyelini hesaplıyor ve bu sonucu digerSayi değişkeninde tutuyor. Peki ya digerSayi değişkeni yerine SayininFaktoriyeli dersek? Bu durumda kodun ne yaptığını bir nebze daha anlaşılabilir kılarız.

Döngü kullanımı

Döngü kullanımı hakkında makalede for/while döngüsü kullanımı hakkında bir bilgi vermiştik. Burada kullanılan while döngüsü yerine for kullanırsak j değişkeninin yönetimi daha kolay olur ve kod oldukça basitleşir, kısalır. Bir de döngünün koşulunu yazarken sıranın öneminden bahsetmiştik. Burada da okunan sayı değerinin j ye büyük eşit olma durumunun sırasını düzeltirsek okunması daha kolay olacaktır.

Gereksiz yorum kullanımı

Koda bakıldığında ne yapıldığını anlayabiliyorsak yorum satırında kodun ne yaptığını belirtmek gereksizdir. Buradaki yorumlar da aslında buna örnektir.

Kodu yazalım

Aşağıda koda bakalım. Eskisi ile arasındaki farklar ne? Yaptığımız küçük değişiklikler sonucunda kodumuz daha temiz, basit, kısa ve anlaşılabilir oldu.

Sonuç

Gelelim sonuca. Aslında bu makalede başta sorduğum “Neden Temiz Koda İhtiyacımız Var?” sorusunu cevaplamaya çalıştım. Temiz kod, bireysel veya kurumsal hayatta yazdığımız kodun;

  • Basit ve kısa.
  • Okunabilir ve açık.
  • Hatadan arındırılmış.

Olmasını sağlar. Bu gibi faktörler yaptığımız işi yaparken o işten zevk almamızı, motive olmamızı ve verimli olmamızı sağlar.

Kaynakça

--

--

Sedat Korkmaz

İzmir Bakırçay Üniversitesi bilgisayar mühendisliği öğrencisi.