Code that is clean and elegant is easier to maintain and extend.
– Dennis Ritchie
C# ile anlaşılması kolay ve derli toplu bir uygulama yazmak için bazı ilkelere uyum sağlamak zorundayız. Karmaşıklığı azaltarak geliştiricilerin aynı proje üzerinde iş birliği içinde çalışmasını kolaylaştırmak adına “clean architecture” elzem bir şeydir.

Temiz kod yazmak, diğer insanların kodunuzu kolayca yorumlayabilmesi için oldukça önemlidir. Robert C. Martin‘in Clean Code kitabına dayanarak C# dilinde birkaç pratik örnekler sunacağım. Bunları bazı başlıklara ayıralım.
Bu bölümde isimlendirme standartlarına değineceğiz.
Değişkenler, metotlar, projeler, solution dosyaları, tablolar, klasörler vb. kod yazarları ve geliştiriciler, anlamlı adlar oluşturmanın genellikle kodu daha sürdürülebilir hale getirdiğinin farkında olmalıdır. Yazılan isim yapılan işleme hizmet etmeli. Dolayısıyla değişkenlere, metotlara ve sınıflara amacı ortaya koyan adlar oluşturmak, programın anlaşılmasını kolaylaştıracaktır.
Örneğin bir ürün getirme işlemi için metod yazıldığını varsayalım.
public C Pr(string bcod)
{
return new C()
{
ab = "S24+",
cd = "Samsung"
};
}Neyin ne olduğunu anlamıyoruz. Bu sebeple doğru bir isimlendirmeyle refactor edelim:
public Catalog GetProduct(string barcodeNumber)
{
return new Catalog()
{
Name = "S24+",
Brand = "Samsung"
};
}Yanıltıcı isimlendirden ve kısaltmalardan kaçının.
Belki uzun vakittir çalışanlar için kısaltmalar sorun olmayabilir ama yeni başlayanlar için kafa karıştırıcı olacaktır. “GetPDate” metod adı bize ne anlatıyor olabilir? Hemen tahmin etmek zor.
public DateTime GetPDate()
{
DateTime pDate = Convert.ToDateTime("2024-05-01");
return pDate;
}Şimdi bunu revize edelim. Daha açık bir isimlendirme tercih etmelisiniz.
public DateTime GetProductDate()
{
DateTime productDate = Convert.ToDateTime("2024-05-01");
return productDate;
}Class ve method isimlendirmeleri nasıl olmalı?
Sınıf isimleri her zaman bir isim olmalıdır. Örneğin Client, BankAccount, School gibi ifadeler bir nesneyi veya kavramı temsil eder. Sınıf adlarında fiil ya da belirsiz isimler kullanmak okunabilirliği düşürür ve sınıfın amacını belirsiz hale getirir.
Metot isimleri ise fiil olmalıdır. Çünkü metotlar bir iş yapar. Örneğin: Insert, Commit, Calculate, GetFullName gibi. Bu sayede metot çağrıldığında hangi eylemi gerçekleştireceği doğrudan anlaşılır. Ayrıca bir projede aynı anlama gelen farklı ön ekler (get, fetch, obtain) kullanılmamalıdır. Bu tür çeşitlilik, hem kafa karıştırır hem de kodu sürdürülebilir olmaktan uzaklaştırır. Daha sonra metot isimlerinin başında olan “Get”, “Post” gibi ifadeleri daha doğru kullanmak için başka bir best practice göstereceğim.
Sonuç olarak, aynı işlevi gören iki metot yazıldığında, daha açıklayıcı isimler seçilen sürüm her zaman tercih edilmelidir. Böylece kodun okunabilirliği, bakımı ve anlaşılabilirliği artar.
Metot iyileştirmeleri
Şimdi aynı işi yapan 2 farklı metot gösterelim.
public void PrintCarCategory(List<Car> cars)
{
foreach (Car c in cars)
{
int power = c.HorsePower;
string category;
if (power < 100)
category = "low";
else if (power > 100 && power < 200)
category = "medium";
else
category = "high";
Console.WriteLine($"The car {c.Model} has {category} power");
}
}Metot doğru çalışıyor olabilir ama doğru bir şekilde mi anlamlandırıldı? Hayır. Çünkü kaçınılması gereken birçok nokta var.
- Anlamsız ve kısa isimler (c, type),
- Sınır değerleri belirsiz ifadeler (> 100 && < 200 ifadesinde 100 ve 200 nereye ait?)
- Sabit sayılar belirlenmemiş (100, 200 doğrudan kodda)
- Tek metotta birden fazla sorumluluk var
Şimdi bunun clean code mimarisine uygun bir sürümü yazarak sorumlulukları ayıralım, isimleri güçlendirelim, sınırları netleştirelim.
public class CarStatistics
{
const string LOW_POWER_CAR = "low";
const string MEDIUM_POWER_CAR = "medium";
const string HIGH_POWER_CAR = "high";
public void PrintCategory(List<Car> cars)
{
foreach (Car car in cars)
{
string category = GetCarCategory(car.HorsePower);
Console.WriteLine($"The car {car.Model} has {category} power");
}
}
public string GetCarCategory(int horsePower)
{
if (horsePower < 100)
return LOW_POWER_CAR;
else if (horsePower > 100 && horsePower < 200)
return MEDIUM_POWER_CAR;
else
return HIGH_POWER_CAR;
}
}
Bu sürümde anlamlı isimler ve sabit değişkenler kullandık, kodun tekrar kullanılabilirliğini artırdık. GetCarCategory metodunu farklı yerlerde (örneğin API cevabında, raporlama ekranında) tekrar kullanabiliriz. Okunabilirliği de arttırdık. Örneğin ileride “orta sınıf araba 200 değil 220 beygire kadar olsun” derseniz, sadece GetCarCategory içindeki koşulu değiştirmeniz yeterli. Kodun diğer kısımları aynı kalır.
Bu tür örnekleri arttırabiliriz ama anlaşılması açısından yeterli olduğu kanaatindeyim.
Diğer bölümümüzde metotlara giriş yapacağız.



Yorum bırakın