Temiz ve Anlaşılır Kod Yazma Nedir?
Temiz ve Anlaşılır Kod yazmak tam olarak nedir bir programlama dilini bilen bilgisayarın anlayacağı basit bir kod yazabilir bunda sorun yok o zaman neden anlaşılır olması için uğraşalım diyebilirsiniz .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.
Ö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.
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
Martin Fowler
Temiz kod ne gibi özellikler taşımalı:
-Kod okunabilirliği özelden genelle gider gibi olmalı kod bir parçasına baktığında bütünün ne anlatmak istediğini ne olduğunu görmemiz gerekir.
-Net olmalı her bir sınıf, entity, business katmanı ya da metod sadece bir amaca hizmet etmeli karmaşadan uzak durulmalıdır.
-Bakımı yapılabilir olmalıdır. Bakımı yazımından daha zor olacak kodlardan kaçınmalıyız :)
-Tüm testlerin başarılı bir şekilde tamamlaması
-Tekrar (duplicate ) olmaması kod tekrarı hem karmaşaya yol açar hem de kod uzadığı için anlaşılabilirliğini de zarar verir.
-Kullanılmayan kodların olmaması.
Temiz kod yazmada can alıcı nokta isimlendirmedir
Doğru isimlendirilmiş bir değişken ,sınıf veya fonksiyon incelemeye vakit harcamanıza gerek bırakmayabilir. 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 bunları yorum satırı olarak yazıyorsanız isimlendirmeniz de bir eksiklik olabilir. Önek ya da altçizgi gibi ifadeler kullanılmamalıdır.
1. Anlaşılır ve örneği olan tanımlamalar kullanmak
Bir parametre , fonksiyon veya sınıf ismi tanımlarken bunu herkesin rahatça anlayabileceği , sınıfın içeriğine bakmadan sadece bu sınıfın ismi ile neler yaptığını anlayabilmesini sağlayacak bir isim kullanılmalıdır. Ayrıca projedeki tüm tanımlamaların İngilizce olmasına dikkat edilmelidir.
public class Alisveris{
public void makeOrder(ProductModel product){}}
yerine:
public class Shopping {
public void makeOrder(ProductModel product){}}
Alışveriş kelimesi ile sınıf ismi Türkçe tanımlanmaya çalışıldı fakat birçok derleyici Türkçe karakter kabul etmeyeceği için ı ve ş karakterleri yok edilerek i ve s harflerine dönüştürülmek zorunda kalındı. Ayrıca projenin diğer ülkelerdeki insanlarla ortak olarak çalışılması için İngilizce kullanılması gerekiyor.
NOT: Sınıf isimleri büyük harfle başlar ve kelimeler bitişik yazılır.Her kelimenin baş harfi büyük olmalıdır.
Fonksiyonlar için iki durum söz konusudur:
Birincisi;ilk kelime küçük harflerle yazılır,sonraki kelimenin baş harfleri büyük yazılır.
Örnek dil:JavaScript
function myFunction(p1, p2) {}
İkincisi ;ilk kelimenin ilk harfi büyük sonraki kelimenin de baş harfleri büyük yazılır.
Örnek dil:C#
private static void EkranaYaz(int[] dizi){}
Yerel değişkenler küçük harfle yazılmalıdır( Yerel değişkenler bir metodun ya da bir blokun iç değişkenlerdir).
2. Bir fonksiyon birden fazla iş yapmamalı
Yazdığımız her fonksiyonun yalnızca bir işi yapması gerekir. Böylelikle bu fonksiyonu hem reusable (tekrar tekrar kullanılabilir) hem de fonksiyonun karmaşıklığını azaltmış oluyoruz.
Örneğin yanlış tanımlama:
public int sumNumbersAndSquare(int a, int b){
int total = a + b;
total = total * total;
return total;}
Doğru tanımlama:
public int sum(int a, int b){
return a + b;}
public int square(int x){
return x * x;}
İki sayıyı toplama ve karesini alma işlemi tek bir fonksiyon içinde tanımlanmış. Halbuki , ilerleyen zamanlarda biz bir sayının sadece karesini hesaplayan bir fonksiyona ihtiyaç duyabiliriz. Bu durumda bu iki işlem için tek bir fonksiyon yazmış olmamış bizi kısıtlar. Bu yüzden toplama ve karesini alma fonksiyonunu sum ve square adlı iki fonksiyona parçalıyoruz.
NOT:Fonksiyon içinde yapılan işlemlerin sonucunu yerel bir değişkene atayarak sonucu döndürün.
3. Hiçbir fonksiyon tekrar etmemeli. Don’t copy, reuse it
Yazdığımız fonksiyonlar ve sınıflar tekrar etmemeli. Gerekiyorsa encapsulation veya inheritanceyapılarak bu modüler sınıfın her yerden instance’ı(örneği) oluşturulabilecek şekilde ayarlanmalıdır. Ki bu zaten OOP ‘nin alanına giriyor.
4. Değişkenler en üstte tanımlanmalı
Yazdığımız bir sınıfta değişkenlerin hepsi en üstte olmalı . Hiçbir sınıf değişkeninden önce fonksiyon tanımı yapılmamalı.
NOT:Sınıf içinde değişken tanım yaparken önce pubic sonra protected daha sonra private değişkenleri yazılmalıdır.bu sıralama yapıldıktan sonra bu üç scope içinden bu sefer değişken tipi için bir sıralama yapılmalıdır. boolean>intger>float>double>string>other and custom classes
5. Bir sınıf çok fazla fonksiyon içermemeli
Eğer yazdığınız sınıftaki fonksiyon sayısı aşırı derecede fazlaysa ( max : 20–30 olmalı ) artık bir sorun var demektir. Sınıfınızda bulunan benzer amaçlı fonksiyonları yeni bir object sınıfı oluştururak encapsule etmelisiniz.
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 bir amacı yada sorumluluğu olmalıdır.Her hangi bir değişiklik yapıldığında bu nesnenin amaç yada sorumluluğu değişmesinden dolayı yapılmalıdır.
O-Open/Closed Principle (OCP): Metod düzenlemelere ,yeni şart ve güncellemelere açıktır.Ancak metod yada nesnenin 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.
Özetleyecek olursak; Temiz kod kodun kaliteli olması açısından önemli ve vakit ayrılması gereken bir aşamadır.