Temiz kod (clean code), başka bir geliştiricinin (ya da altı ay sonraki sizin) okuyabildiği, anlayabildiği ve güvenle değiştirebildiği koddur. Mesele zekice numaralar yapmak ya da bir stil rehberini kelimesi kelimesine uygulamak değildir. Amaç, gelecekte yapılacak her değişikliğin maliyetini düşürmektir.
Bu rehberde temiz kodun altın kurallarını JavaScript, PHP ve SQL ile kısa, pratik örnekler üzerinden inceliyor ve bir sonraki kod incelemenizde kullanabileceğiniz bir kontrol listesiyle bitiriyoruz.
Temiz Kod Neden Önemlidir?
Bir yazılım projesinin ömrünün büyük bölümü bakım ve güncellemelerle geçer. Robert C. Martin'in Clean Code kitabında belirttiği gibi, kod okumaya harcadığımız zaman, kod yazmaya harcadığımız zamandan çok daha fazladır. Temiz kod, gelecekteki kendimize ve takım arkadaşlarımıza bırakabileceğimiz en değerli mirastır.
Dağınık kodun gerçek bir maliyeti vardır:
- Yavaşlayan geliştirme: kimse bir kod parçasının tam olarak ne yaptığından emin olmadığı için her değişiklik daha uzun sürer.
- Daha fazla hata: gizli yan etkiler ve tekrarlanan mantık, hiç beklemediğiniz yerlerde bozulur.
- Zorlaşan adaptasyon: yeni ekip üyelerinin verimli hale gelmesi günler yerine haftalar sürer.
- Değişiklik korkusu: kod zor anlaşıldığında kimse onu iyileştirmeye cesaret edemez ve sorun büyür.
Temiz Kodun Altın Kuralları
1. Anlamlı İsimler Kullanın
Değişken, fonksiyon ve sınıf isimleri ne tuttuklarını ya da ne yaptıklarını açıkça söylemelidir. $d, $list1 veya get_stuff() gibi belirsiz isimlerden kaçının. İyi bir isim, yoruma olan ihtiyacı ortadan kaldırır.
// KÖTÜ
let d = 20; // 20 ne? Gün mü? Yaş mı?
function handle(u) { /* ... */ }
// İYİ
const maxLoginAttempts = 20;
const elapsedTimeInDays = 20;
function sendWelcomeEmail(user) { /* ... */ }
Her dilde işe yarayan basit isimlendirme kuralları:
- Fonksiyonlar fiildir (
calculateTotal,sendInvoice); sınıflar ve değişkenler isimdir (Invoice,activeUsers). - Boolean değerler bir soru gibi okunmalıdır:
isActive,hasPermission,canRetry. - Her kavram için tek bir kelime kullanın. Aynı tür işlem için
fetch,getveretrievekelimelerini karıştırmayın. - Sihirli sayıları (magic numbers) isimlendirilmiş sabitlerle değiştirin.
2. Fonksiyonlar Tek Bir İş Yapmalı
Bir fonksiyon tek bir iş yapmalı, onu iyi yapmalı ve sadece onu yapmalıdır. Fonksiyonunuz "kullanıcıyı getiriyor, e-postayı doğruluyor ve hoş geldin e-postası gönderiyorsa" üç ayrı iş yapıyordur. Bu fikir Tek Sorumluluk İlkesi (Single Responsibility Principle - SRP) ile yakından ilişkilidir: bir kod biriminin değişmek için yalnızca bir nedeni olmalıdır.
// KÖTÜ: tek fonksiyon, üç sorumluluk
function register(array $data)
{
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
$id = $this->db->table('users')->insert($data);
mail($data['email'], 'Welcome!', 'Thanks for joining.');
return $id;
}
// İYİ: açık isimli küçük fonksiyonlar
function register(array $data): int
{
$this->validateRegistration($data);
$userId = $this->users->create($data);
$this->mailer->sendWelcome($data['email']);
return $userId;
}
Küçük fonksiyonları isimlendirmek, test etmek ve yeniden kullanmak daha kolaydır. Pratik bir kural: bir fonksiyonun ne yaptığını "ve" kelimesini kullanmadan anlatamıyorsanız, muhtemelen çok fazla iş yapıyordur.
3. Fonksiyonları Kısa ve Düz Tutun
İç içe geçmiş if blokları, okuyucuyu aynı anda birçok koşulu aklında tutmaya zorlar. Önce istisnai durumları ele almak ve ana akışı düz tutmak için guard clause (erken dönüş) kullanın.
// KÖTÜ: iç içe koşullar
function getDiscount(user) {
if (user) {
if (user.isActive) {
if (user.orders > 10) {
return 0.15;
}
}
}
return 0;
}
// İYİ: guard clause
function getDiscount(user) {
if (!user || !user.isActive) return 0;
if (user.orders <= 10) return 0;
return 0.15;
}
4. Fonksiyon Parametrelerini Sınırlayın
Beş sıralı parametre alan bir fonksiyonu doğru çağırmak zordur. Üçüncü parametredeki true "e-posta gönder" için miydi, yoksa "yönetici mi" için mi? Bir fonksiyon çok sayıda değere ihtiyaç duyuyorsa bunları bir nesne veya küçük bir veri sınıfında toplayın ve davranışı değiştiren boolean bayrak parametrelerinden kaçının.
// KÖTÜ
createUser('Ada', 'ada@example.com', true, false, 'admin');
// İYİ
createUser({ name: 'Ada', email: 'ada@example.com', role: 'admin', sendWelcome: true });
5. Aşırı Yorum Satırından Kaçının
İyi yazılmış kod kendi kendini belgelemelidir. Bir bloğun ne yaptığını anlatmak için uzun bir yoruma ihtiyaç duyuyorsanız, muhtemelen o bloğu daha anlaşılır şekilde yeniden yazmanız, örneğin iyi isimlendirilmiş bir fonksiyona taşımanız gerekiyordur. Yorumlar kodun ne yaptığını değil, neden o şekilde yazıldığını açıklamak içindir.
"Kötü kodu yorumlamayın, yeniden yazın." — Brian W. Kernighan ve P. J. Plauger
İyi yorumlar iş kurallarını, yasal gereklilikleri, üçüncü parti hatalar için yapılan geçici çözümleri ya da şaşırtıcı bir kararın arkasındaki nedeni açıklar. Yorum satırına alınmış eski kodun depoda yeri yoktur; sürüm kontrol sistemi onu zaten hatırlar.
6. Kendinizi Tekrar Etmeyin (DRY)
Aynı kod bloğunu projenin farklı yerlerine kopyalayıp yapıştırırsanız, gelecekteki her değişikliği birkaç yerde yapmanız gerekir ve er ya da geç bunlardan biri unutulur. Ortak mantığı yeniden kullanılabilir bir fonksiyona, servise veya yardımcıya (helper) taşıyın.
Yine de DRY'ı aşırıya kaçırmamaya dikkat edin. Bugün birbirine benzeyen ama farklı nedenlerle değişen iki kod parçası aslında tekrar sayılmaz. Onları erkenden birleştirmek yanlış bir soyutlama oluşturur.
7. Hataları Açıkça Ele Alın
Temiz kod hataları gizlemez. -1 veya false gibi sihirli değerler döndürmek yerine açık mesajlı istisnalar (exception) fırlatın ve hataları asla boş bir catch bloğunda yutmayın.
// KÖTÜ: hata sessizce kayboluyor
try {
$payment->charge($order);
} catch (Exception $e) {
}
// İYİ: logla ve kararı çağıran tarafa bırak
try {
$payment->charge($order);
} catch (PaymentFailedException $e) {
log_message('error', 'Payment failed for order {id}: {msg}', ['id' => $order->id, 'msg' => $e->getMessage()]);
throw $e;
}
8. Tutarlı Bir Biçimlendirme Kullanın
Biçimlendirme süs değildir: tutarlı girinti, boşluk ve dosya yapısı okuyucunun mantığa odaklanmasını sağlar. Bir standartta anlaşın (örneğin PHP için PSR-12 veya JavaScript için Prettier) ve bunu araçların otomatik uygulamasına bırakın; böylece kod incelemelerinde bir daha boşluk ve parantez tartışılmaz.
9. Test Yazın
Yeniden düzenlemeyi (refactoring) güvenli kılan şey testlerdir. Testler olmadan her temizlik bir risktir; testlerle ise kodu güvenle yeniden isimlendirebilir, bölebilir ve sadeleştirebilirsiniz. Testleri de okunabilir tutun: her testte tek bir davranış, it_rejects_an_invalid_email gibi açık bir isim ve testin içinde karmaşık mantık olmasın.
10. Kodu Bulduğunuzdan Daha Temiz Bırakın
"İzci Kuralı" (Boy Scout Rule), kamp alanını bulduğunuzdan daha temiz bırakmanız gerektiğini söyler. Büyük bir yeniden yazıma gerek yok. Bir dosyaya her dokunduğunuzda belirsiz bir değişkeni yeniden isimlendirin, uzun bir koşulu ayırın ya da ölü bir kod parçasını silin. Küçük ve sürekli iyileştirmeler bir kod tabanını sağlıklı tutar.
SQL'de Temiz Kod
Temiz kod kuralları sadece uygulama kodu için geçerli değildir. SQL sorguları da en az o kadar sık okunur ve değiştirilir; dağınık sorgular, hataların ve yavaş sayfaların yaygın bir kaynağıdır.
- Anahtar kelimeleri tutarlı yazın (örneğin büyük harfle
SELECT,FROM,WHERE) ve her ifadeyi ayrı bir satıra koyun. SELECT *yerine sadece ihtiyacınız olan kolonları seçin. Bu hem niyetinizi belgeler hem de gereksiz veri yüklemeyi önler.- Anlamlı takma adlar (alias) kullanın:
a,b,cyerineorders ovecustomers cgibi. - Açık JOIN kullanın; tabloları
FROMiçinde sıralayıpWHEREiçinde birleştirmeyin. - Karmaşık sorguları CTE'lere bölün (
WITH ... AS); böylece her adımın bir adı olur. - Tablo ve kolonları tutarlı isimlendirin (örneğin snake_case ve çoğul tablo adları) ve bunu tüm şemada koruyun.
- Kullanıcı girdisini sorguya eklemek yerine her zaman parametre kullanın. Bu hem daha temizdir hem de SQL injection saldırılarını önler.
-- KÖTÜ
select * from orders a, customers b where a.cid=b.id and a.status='paid' and a.created_at>'2026-01-01'
-- İYİ
WITH paid_orders AS (
SELECT o.id, o.customer_id, o.total, o.created_at
FROM orders o
WHERE o.status = 'paid'
AND o.created_at >= :start_date
)
SELECT c.name,
COUNT(p.id) AS order_count,
SUM(p.total) AS revenue
FROM paid_orders p
JOIN customers c ON c.id = p.customer_id
GROUP BY c.name
ORDER BY revenue DESC;
İndeksler ve N+1 sorgu problemi gibi SQL'in performans tarafı için veritabanı optimizasyonu ve Redis caching rehberimize göz atabilirsiniz.
Temiz Kod Kontrol Listesi
Bir pull request açmadan önce bu kısa listeyi kullanın:
- Her isim, uygulamasını okumadan anlaşılabiliyor mu?
- Her fonksiyon tek bir iş yapıyor ve kaydırmadan okunabilecek kadar kısa mı?
- İstisnai durumlar derin iç içe bloklar yerine erken dönüşlerle mi ele alınıyor?
- Sihirli sayı, tekrarlanan blok veya yorum satırına alınmış kod kaldı mı?
- Hatalar açıkça ele alınıyor ve gerektiğinde loglanıyor mu?
- Kod, ekip standardına göre otomatik olarak biçimlendiriliyor mu?
- Eklediğiniz veya değiştirdiğiniz davranışı testler kapsıyor mu?
- SQL sorguları parametreli, okunabilir ve sadece gerekli kolonları mı seçiyor?
Sonuç
Temiz kod yazmak bir gecede öğrenilen bir beceri değil, her gün pratik edilen bir disiplindir. Anlamlı isimler ve küçük fonksiyonlarla başlayın, güvenle yeniden düzenleyebilmek için testler ekleyin ve aynı özeni SQL sorgularınıza da gösterin. Takım arkadaşlarınız ve gelecekteki kendiniz size teşekkür edecek. Unutmayın: kodunuzu okuyacak ilk kişi sizsiniz.
Henüz hiç yorum yapılmamış. İlk yorumu siz yapın!