Clean Code Prensipleri: Okunabilir Kod Yazma
Clean Code Nedir ve Neden Önemlidir?
Yazılım geliştirme dünyasında kod yazmak işin yalnızca yarısıdır; asıl zorluk, başkalarının — ve gelecekteki kendinizin — kolayca anlayabileceği kod yazmaktır. Robert C. Martin'in ünlü kitabı "Clean Code" ile popülerleşen temiz kod prensipleri, yazılım projelerinin sürdürülebilirliğini ve kalitesini doğrudan etkiler. Bir kod satırı yazıldıktan sonra ortalama 10 kez okunur. Bu gerçek bile tek başına okunabilirliğin neden kritik olduğunu açıklamaya yeter.
Temiz kod; anlaşılması kolay, değiştirilmesi güvenli ve test edilmesi basit olan koddur. Şimdi bu hedefe ulaşmak için uygulanması gereken temel prensiplere derinlemesine bakalım.
1. Anlamlı ve Açıklayıcı İsimlendirme
Değişken, fonksiyon ve sınıf isimleri kodunuzun en güçlü dokümantasyon aracıdır. İyi bir isim, okuyucunun kodu anlamak için ekstra çaba harcamasını gereksiz kılar.
Kötü İsimlendirme Örneği
// Ne yaptığı belirsiz
function calc(a, b, c) {
return a * b * (1 - c);
}
let d = calc(100, 5, 0.18);
İyi İsimlendirme Örneği
function calculateDiscountedPrice(unitPrice, quantity, discountRate) {
return unitPrice * quantity * (1 - discountRate);
}
let totalPrice = calculateDiscountedPrice(100, 5, 0.18);
İsimlendirme konusunda şu kurallara dikkat edin:
- Kısaltmalardan kaçının:
usryerineuser,btnyerinebuttonyazın. - Bağlamı yansıtın: Bir değişken neyi temsil ediyorsa ismi onu söylemelidir.
- Boolean değişkenlerde soru formatı kullanın:
isActive,hasPermission,canEditgibi. - Tutarlı olun: Projede
fetchkullanıyorsanız aynı işlem için başka yerdegetveyaretrievekullanmayın.
2. Fonksiyonlar: Tek Sorumluluk, Küçük Boyut
Clean Code'un en temel kurallarından biri şudur: bir fonksiyon yalnızca bir iş yapmalıdır ve o işi iyi yapmalıdır. Bir fonksiyon 20-30 satırı geçiyorsa, muhtemelen birden fazla sorumluluk taşıyordur.
Kötü Örnek: Her Şeyi Yapan Fonksiyon
function processOrder(order) {
// Stok kontrolü
for (let item of order.items) {
let stock = db.query(`SELECT stock FROM products WHERE id = ${item.id}`);
if (stock < item.quantity) {
throw new Error('Stok yetersiz: ' + item.name);
}
}
// Fiyat hesaplama
let total = 0;
for (let item of order.items) {
total += item.price * item.quantity;
}
if (order.coupon) {
total *= (1 - order.coupon.discount);
}
// Ödeme işlemi
paymentGateway.charge(order.userId, total);
// Veritabanına kayıt
db.insert('orders', { userId: order.userId, total: total, items: order.items });
// E-posta gönder
emailService.send(order.userEmail, 'Siparişiniz alındı', buildTemplate(order));
}
İyi Örnek: Ayrıştırılmış Fonksiyonlar
function processOrder(order) {
validateStock(order.items);
let total = calculateTotal(order.items, order.coupon);
chargePayment(order.userId, total);
saveOrder(order, total);
sendConfirmationEmail(order);
}
function validateStock(items) {
for (let item of items) {
let stock = inventory.getStock(item.id);
if (stock < item.quantity) {
throw new InsufficientStockError(item.name);
}
}
}
function calculateTotal(items, coupon) {
let subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
return coupon ? subtotal * (1 - coupon.discount) : subtotal;
}
Bu yaklaşımın avantajları:
- Her fonksiyon bağımsız olarak test edilebilir.
- Bir hata oluştuğunda sorunlu alan hızla izole edilir.
- Fonksiyon isimleri doğal bir dokümantasyon görevi görür.
- Kod tekrar kullanılabilirliği (reusability) artar.
3. Yorum Satırları: Az Ama Öz
Yaygın bir yanılgı, çok yorum yazmanın iyi bir pratik olduğudur. Gerçekte ise en iyi yorum, yazmak zorunda olmadığınız yorumdur. Kodunuz kendini açıklayabiliyorsa yorum gereksizdir. Yorumlar yalnızca neden sorusuna cevap vermek için kullanılmalıdır.
Gereksiz Yorum
// Kullanıcının yaşını kontrol et
if (user.age >= 18) {
// Erişime izin ver
grantAccess();
}
Değerli Yorum
// KVKK gereği 18 yaş altı kullanıcılar veli onayı olmadan
// kişisel veri işleme kapsamındaki hizmetlere erişemez.
if (user.age >= 18) {
grantAccess();
}
İlk örnekte yorum, kodun zaten söylediğini tekrar eder ve gürültü yaratır. İkinci örnekte ise arkasındaki iş kuralı açıklanır; bu bilgi koddan çıkarılamaz.
4. DRY Prensibi: Kendini Tekrar Etme
DRY (Don't Repeat Yourself), tekrarlanan kod bloklarının tek bir soyutlama altında birleştirilmesini önerir. Aynı mantık birden fazla yerde tekrarlanıyorsa, bir değişiklik yapmanız gerektiğinde tüm kopyaları güncellemeniz gerekir — ve en az birini unutma olasılığınız yüksektir.
// KÖTÜ: Tekrarlanan doğrulama mantığı
function createUser(data) {
if (!data.email || !data.email.includes('@')) {
throw new ValidationError('Geçersiz e-posta');
}
// ...
}
function updateUser(data) {
if (!data.email || !data.email.includes('@')) {
throw new ValidationError('Geçersiz e-posta');
}
// ...
}
// İYİ: Tek noktada doğrulama
function validateEmail(email) {
if (!email || !email.includes('@')) {
throw new ValidationError('Geçersiz e-posta');
}
}
function createUser(data) {
validateEmail(data.email);
// ...
}
function updateUser(data) {
validateEmail(data.email);
// ...
}
5. Hata Yönetimi: Sessiz Başarısızlıktan Kaçının
Temiz kod, hataları gizlemez; onları açıkça ve anlaşılır şekilde yönetir. Boş catch blokları, null döndürerek hatayı yutma gibi pratikler, hata ayıklamayı kabusa çevirir.
// KÖTÜ: Hatayı yutmak
try {
let data = JSON.parse(rawInput);
} catch (e) {
// sessizce geç
}
// İYİ: Hatayı anlamlı şekilde yönetmek
try {
let data = JSON.parse(rawInput);
} catch (error) {
throw new InvalidInputError(
`Giriş verisi JSON olarak ayrıştırılamadı: ${error.message}`
);
}
6. Kod Formatı ve Tutarlılık
Girintileme, boşluklar, satır uzunluğu ve dosya organizasyonu gibi biçimsel unsurlar okunabilirliği doğrudan etkiler. Ekip genelinde bir stil rehberi (ESLint, Prettier, Black gibi araçlarla desteklenen) belirlenmeli ve otomatik olarak uygulanmalıdır.
- Dikey boşluk: Mantıksal bölümleri boş satırlarla ayırın; birbiriyle ilişkili satırları bir arada tutun.
- Yatay boşluk: Satır uzunluğunu 80-120 karakter arasında tutun.
- Dosya boyutu: Bir dosya 200-300 satırı geçiyorsa bölünmeyi düşünün.
- Import sırası: Standart kütüphane, üçüncü parti paketler, proje modülleri şeklinde gruplandırın.
7. KISS ve YAGNI: Basitliği Koruyun
KISS (Keep It Simple, Stupid) ve YAGNI (You Aren't Gonna Need It) prensipleri, gereksiz karmaşıklıktan kaçınmayı öğütler. Henüz ihtiyaç duyulmayan özellikler için altyapı kurmayın, "belki ileride lazım olur" diye soyutlama katmanları eklemeyin. Bugünün gereksinimlerini karşılayan en basit çözüm, en doğru çözümdür.
Sonuç: Temiz Kod Bir Alışkanlıktır
Clean Code prensipleri bir gecede benimsenen kurallar değil, zamanla geliştirilen bir disiplindir. Her kod incelemesi (code review), her yeniden düzenleme (refactoring) ve her hata ayıklama seansı, daha temiz kod yazma yolunda bir adımdır. Unutmayın: kod yazmak makinelerle iletişim kurmak değil, diğer geliştiricilerle iletişim kurmaktır. Kodunuzu, onu ilk kez okuyan birinin kolayca anlayabileceği şekilde yazmayı hedefleyin — o kişi altı ay sonra siz olabilirsiniz.
- Anlamlı isimler seçin, kısaltmalardan kaçının.
- Fonksiyonları küçük ve tek sorumlu tutun.
- Yorumları "neden" sorusuna cevap vermek için kullanın.
- Kendinizi tekrar etmeyin (DRY).
- Hataları açıkça yönetin, asla yutmayın.
- Tutarlı format kuralları belirleyin ve otomatikleştirin.
- Basitliği her zaman karmaşıklığa tercih edin.