Kod Tekrarından (DRY Prensibi) Nasıl Kaçınılır?
Yazılım projelerinde DRY (Don't Repeat Yourself) prensibi, kod tekrarını önleyip bakım maliyetini düşürür. Fonksiyonelleştirme ve modüler yapı temel çözüm yöntemleridir.

İÇİNDEKİLER
%0 okundu
- DRY (Don't Repeat Yourself) Prensibi Nedir ve Kurumsal Mimarideki Yeri
- Kod Tekrarının (WET) Proje Maliyetlerine ve Bakım Süreçlerine Yıkıcı Etkisi
- Yazılımda Kod Tekrarını Önlemenin Temel ve Etkili Yöntemleri
- Kritik Uyarı: DRY Prensibini Uygularken Düşülen Tuzaklar ve Riskler
- Sürdürülebilirlik İçin DRY, KISS ve SOLID Prensiplerinin Birlikteliği
- Temiz Kod ve Düşük Bakım Maliyeti İçin Sürdürülebilir Yazılım Stratejileri
Yazılım projelerinin başarısı, geliştirme hızından ziyade uzun vadeli bakım kolaylığı, kod kalitesi ve ölçeklenebilirlik ile ölçülür. Kod tabanının kontrolsüz büyümesi ve aynı işlevlerin farklı dosyalarda yinelenmesi, zamanla projeyi yönetilemez bir teknik borç sarmalına sürükler. Bu teknik rehber, yazılım mimarisi kalitesini doğrudan etkileyen Kod Tekrarından (DRY Prensibi) Nasıl Kaçınılır? sorusuna kurumsal düzeyde yanıtlar aramaktadır. İşletme sahipleri, ürün yöneticileri ve teknik karar vericiler için hazırlanan bu içerikte; sürdürülebilir kod yapıları oluşturma, modüler programlama prensipleri, yeniden kullanılabilirlik avantajları ve yaygın refactoring hatalarını aşma yöntemleri, doğrulanabilir sektörel pratikler eşliğinde derinlemesine analiz edilmektedir.
DRY (Don't Repeat Yourself) Prensibi Nedir ve Kurumsal Mimarideki Yeri
DRY (Don't Repeat Yourself - Kendini Tekrar Etme) prensibi, ilk kez Andy Hunt ve Dave Thomas tarafından kaleme alınan The Pragmatic Programmer kitabında formüle edilmiş, modern yazılım mühendisliğinin en temel yapı taşlarından biridir. Bu prensip, popüler inanışın aksine sadece "aynı kod satırlarını kopyalayıp yapıştırmamak" anlamına gelmez. Prensibin özü, bir sistem içindeki her bilgi veya iş mantığı (business logic) parçasının tek, net ve yetkili bir temsilciye (single, unambiguous, authoritative representation) sahip olması gerektiğidir. Yazılım mimarisi tasarlanırken, bilginin tek bir yerde tanımlanması, o bilgiye bağlı tüm süreçlerin tutarlı bir şekilde güncellenmesini ve yönetilmesini mümkün kılar.
Kurumsal yazılım mimarisinde DRY prensibinin yokluğu, bilgi dağınıklığına yol açar. Örneğin, bir e-ticaret platformunda KDV hesaplama mantığının hem sepet ekranında, hem faturalandırma modülünde, hem de mobil API uçlarında ayrı ayrı yazıldığını varsayalım. Yasal mevzuatta yapılan tek bir oran değişikliği, bu hesaplama mantığının sistem genelinde onlarca farklı noktada aranmasını, değiştirilmesini ve her bir noktanın ayrı ayrı test edilmesini gerektirir. DRY prensibine uygun olarak tasarlanmış bir mimaride ise bu mantık, tek bir mikro servis veya merkezi bir kütüphane içindeki yetkili fonksiyon tarafından yürütülür. Böylece, kurumsal bilgi tek bir kaynaktan (Single Source of Truth - SSoT) dağıtılır.
WET (Write Everything Twice veya We Enjoy Typing - Her Şeyi İki Kez Yaz) prensibi ise DRY’ın tam zıttıdır. WET yaklaşımı, kod tabanında kontrolsüz bir kod kopyalama alışkanlığı yaratarak yazılımın "kod çürümesi" (software rot) adı verilen yapısal bozulma sürecine girmesine neden olur. Kurumsal organizasyonlarda, farklı ekiplerin birbirinden habersiz şekilde benzer işlevleri yürüten kod blokları yazması, sistemler arası entegrasyonu zorlaştırır ve veri tutarsızlıklarına zemin hazırlar.
Uzun vadeli bir dijital ürün stratejisinde DRY prensibi, sadece kod düzeyinde değil, veritabanı şemalarından test senaryolarına, API dokümantasyonlarından CI/CD (Sürekli Entegrasyon / Sürekli Dağıtım) boru hatlarına kadar tüm yaşam döngüsü boyunca uygulanmalıdır. Bu yaklaşım, sistemin esnekliğini artırırken, yeni özelliklerin (features) pazara sunulma süresini (time-to-market) radikal bir biçimde kısaltır.
Kod Tekrarının (WET) Proje Maliyetlerine ve Bakım Süreçlerine Yıkıcı Etkisi
Kod tekrarı, kısa vadede hızlı teslimat yapıldığı yanılsamasını yaratsa da, orta ve uzun vadede işletmeler için en büyük finansal ve operasyonel engellerden birine dönüşür. Yazılım endüstrisindeki araştırmalar, bir yazılım projesinin toplam yaşam döngüsü maliyetinin yaklaşık %60 ila %80'inin bakım (maintenance) faaliyetlerine harcandığını göstermektedir. Kontrolsüz bir şekilde biriken teknik borç (technical debt), geliştiricilerin yeni özellikler üretmek yerine, sürekli olarak eski kodlardaki hataları ayıklamakla (debugging) uğraşmasına neden olur ve bu durum doğrudan bakım maliyeti kalemlerini şişirir.
Siber güvenlik ve veri gizliliği (KVKK/GDPR) bağlamında ele alındığında, kod tekrarı çok daha kritik riskler barındırır. Örneğin, bir web uygulamasında kullanıcı girdilerini sterilize eden (input sanitization) güvenlik kontrolü kodlarının projenin farklı alanlarında tekrarlandığını düşünelim. SQL Injection veya Cross-Site Scripting (XSS) açıklarını kapatmak amacıyla bu kontrollerin güncellenmesi gerektiğinde, tek bir noktanın gözden kaçırılması tüm sistemi saldırılara açık hale getirebilir. OWASP (Open Web Application Security Project) standartlarına uyum sağlamak isteyen kurumsal şirketler, tekrarlı kod yapıları yüzünden güvenlik denetimlerinden (audit) geçmekte zorlanırlar ve bu da hem prestij hem de ciddi finansal cezalar olarak geri dönebilir.
Ayrıca, tekrarlı kod tabanları üzerinde yazılan birim testlerin (unit tests) yazım ve bakım süreçleri de hantallaşır. Aynı iş mantığına sahip beş farklı kod bloğu için beş ayrı test yazılması gerekir. Kodun davranışında yapılacak küçük bir değişiklik, tüm bu testlerin kırılmasına (broken tests) yol açar. Geliştiriciler, testleri güncellemek için harcadıkları efor yüzünden bir süre sonra test yazma alışkanlığından vazgeçebilirler. Bu durum, yazılımın genel kalitesini ve sürdürülebilirlik seviyesini doğrudan düşürür.
Yazılımda Kod Tekrarını Önlemenin Temel ve Etkili Yöntemleri
Fonksiyonelleştirme ve Metot Optimizasyonu
Kod tekrarından kaçınmanın ilk ve en temel adımı, tekrar eden mantıksal süreçleri bağımsız fonksiyonlara (functions) veya metotlara (methods) dönüştürmektir. Eğer projenizde aynı kod satırlarını iki veya daha fazla yerde görüyorsanız, bu blokları parametrik bir yapıya kavuşturarak tek bir fonksiyona taşımalısınız. Bu işlem sadece satır sayısını azaltmakla kalmaz, aynı zamanda kodun okunabilirliğini ve test edilebilirliğini de artırır.
Aşağıdaki TypeScript örneğinde, bir kurumsal e-ticaret sistemindeki kullanıcı yetkilendirme ve loglama işlemlerinin refactoring öncesi ve sonrası durumları incelenebilir:
// Refactoring Öncesi (WET Yaklaşımı)
function processInvoice(user: User, invoice: Invoice) {
if (user.role !== 'admin' && user.permissions.indexOf('manage_invoices') === -1) {
throw new Error('Yetkisiz erişim denemesi: ' + user.id);
}
console.log(`[LOG] fatura işlemi başlatıldı. Kullanıcı: ${user.id}, Zaman: ${new Date().toISOString()}`);
// Fatura işleme mantığı...
}
function deleteProduct(user: User, productId: string) {
if (user.role !== 'admin' && user.permissions.indexOf('manage_products') === -1) {
throw new Error('Yetkisiz erişim denemesi: ' + user.id);
}
console.log(`[LOG] ürün silme işlemi başlatıldı. Kullanıcı: ${user.id}, Zaman: ${new Date().toISOString()}`);
// Ürün silme mantığı...
}// Refactoring Sonrası (DRY Yaklaşımı)
function verifyPermission(user: User, requiredPermission: string): void {
const hasAccess = user.role === 'admin' || user.permissions.includes(requiredPermission);
if (!hasAccess) {
throw new Error(`Yetkisiz erişim denemesi: ${user.id}`);
}
}
function writeAuditLog(userId: string, action: string): void {
const timestamp = new Date().toISOString();
console.log(`[LOG] ${action} işlemi başlatıldı. Kullanıcı: ${userId}, Zaman: ${timestamp}`);
}
function processInvoiceDry(user: User, invoice: Invoice) {
verifyPermission(user, 'manage_invoices');
writeAuditLog(user.id, 'fatura');
// Fatura işleme mantığı...
}
function deleteProductDry(user: User, productId: string) {
verifyPermission(user, 'manage_products');
writeAuditLog(user.id, 'ürün silme');
// Ürün silme mantığı...
}Yukarıdaki kod iyileştirme işlemi sayesinde, gelecekte yetkilendirme mantığına "iki faktörlü doğrulama (2FA) kontrolü" gibi yeni bir kural eklenmesi gerektiğinde, bu değişiklik yalnızca verifyPermission fonksiyonu içerisinde yapılacaktır. Bu durum, yazılım mimarisi genelinde hata yapma payını sıfıra indirir.
Modüler Mimari ve Bileşen (Component) Tabanlı Geliştirme
Modern yazılım geliştirme süreçlerinde, özellikle React, Vue, Angular gibi kütüphanelerin yükselişiyle birlikte bileşen tabanlı mimari (component-based architecture) bir standart haline gelmiştir. Bileşen tabanlı geliştirme, kullanıcı arayüzlerini ve iş mantıklarını bağımsız, kendi kendine yetebilen ve yeniden kullanılabilir (reusable) parçalara bölmeyi hedefler.
Modüler programlama, backend sistemlerde ise kendini mikro servis mimarileri, bağımsız kütüphaneler (npm paketleri, NuGet paketleri, Python tekerlekleri vb.) veya monolitik yapılar içindeki katmanlı mimariler şeklinde gösterir. Ortak kullanılan veri doğrulama mantıkları, API istek yöneticileri veya veri formatlama yardımcıları (helpers), projenin ana gövdesinden soyutlanarak ayrı birer modül haline getirilmelidir. Bu sayede, kurum içi farklı projeler bile aynı ortak kütüphaneleri kullanarak standartlarını eşitleyebilir.
Sistem Çapında Değişken ve Sabit (Constant) Yönetimi
Kod içinde kullanılan "büyülü sayılar" (magic numbers) veya statik metinler (string literals), kod tekrarının en sinsi biçimleridir. Örneğin, bir veritabanı bağlantı zaman aşımı süresinin (timeout) veya sistem genelinde geçerli olan maksimum dosya yükleme sınırının kodun farklı yerlerinde @@CODE0@@ (milisaniye) veya @@CODE1@@ (MB) olarak doğrudan yazılması (hardcoding), sürdürülebilir kod ilkelerine aykırıdır.
Bu değerlerin sistem genelinde tek bir sabitler (constants) dosyasında, çevre değişkenleri (.env dosyaları) içinde veya merkezi bir yapılandırma sunucusunda (Consul, Spring Cloud Config vb.) saklanması gerekir. Böylece operasyon ekipleri, kodu yeniden derlemeye (recompile) gerek kalmadan sadece yapılandırma dosyasını güncelleyerek sistem davranışını değiştirebilirler.
Mevcut bir projede tekrarlı kodları bulup merkezi hale getirmek için izlenmesi gereken adımlar. SonarQube veya ESLint gibi araçları CI/CD hattına entegre ederek yinelenen kod bloklarını ve teknik borç oranını analiz edin. Tekrarlanan mantığın genel bir fonksiyona mı, modüle mi yoksa bağımsız bir mikro servise mi aktarılacağına karar verin. Refactoring işlemine başlamadan önce, mevcut kodun davranışını garanti altına alacak test kapsamını (test coverage) oluşturun veya güncelleyin. Tekilleştirilen yeni yapıyı sisteme entegre edin ve geriye dönük uyumluluk testleri (regression tests) ile sistem kararlılığını onaylayın.Kod Tekrarını Ayıklama ve Refactoring Süreci
Statik Analiz Araçları ile Tespit
Soyutlama Seviyesini Belirleme
Birim Testlerini Hazırlama
Kademeli Entegrasyon ve Test
Kritik Uyarı: DRY Prensibini Uygularken Düşülen Tuzaklar ve Riskler
Yanlış Soyutlama (Wrong Abstraction) Tehlikesi
DRY prensibinin en büyük yanılgısı, birbirine sadece "geçici olarak benzeyen" iki farklı iş sürecini tek bir fonksiyona zorla sıkıştırmaktır. Ünlü yazılım mimarı Sandi Metz'in belirttiği gibi: "Duplication is far cheaper than the wrong abstraction." (Kod tekrarı, yanlış soyutlamadan çok daha ucuzdur).
Eğer iki farklı kod bloğu bugün aynı algoritmayı kullanıyor ancak gelecekte tamamen farklı iş gereksinimlerine göre evrilme potansiyeli taşıyorsa, bunları birleştirmek ölümcül bir hata olabilir. Bu duruma "tesadüfi benzerlik" (accidental duplication) denir. Örneğin, bir sistemdeki müşteri fatura adresi doğrulama mantığı ile tedarikçi depo adresi doğrulama mantığı başlangıçta tamamen aynı olabilir. Ancak, gelecekte mevzuat gereği müşteri adresleri için ek bir doğrusal kimlik kontrolü gerekirken, tedarikçi adresleri için bu gerekmediğinde; tekilleştirilmiş ortak fonksiyona sürekli olarak if-else koşulları ve parametreler eklenmeye başlar. Bu durum, kodu okunamaz ve değiştirilemez bir spagetti yığını haline getirir.
Aşırı Mühendislik (Over-Engineering) ve Üçler Kuralı (Rule of Three)
Yazılım geliştirme süreçlerinde, ileride tekrar edebileceği tahminiyle daha ilk günden karmaşık genel tasarımlar yapmaya çalışmak, aşırı mühendislik (over-engineering) olarak adlandırılır. Bu durum, geliştiricilerin gereksiz yere vakit kaybetmesine ve kodun anlaşılmasının zorlaşmasına neden olur (YAGNI - You Aren't Gonna Need It prensibinin ihlali).
Bu tuzağa düşmemek için pragmatik bir yaklaşım olan "Üçler Kuralı" (Rule of Three) benimsenmelidir:
Bir işi ilk kez yapıyorsanız, kodu doğrudan yazın.
Aynı işi ikinci kez yapıyorsanız, kod tekrarını sineye çekebilirsiniz (ancak aklınızda bulundurun).
Aynı işi üçüncü kez yapıyorsanız, artık o kodu kesinlikle soyutlamalı, ortak bir fonksiyona veya modüle dönüştürmelisiniz.
Bu basit kural, geliştiricilerin erken soyutlama (premature optimization) yapmasını engeller ve gerçek ihtiyaçlara dayalı, sağlıklı bir kod tabanının oluşmasına katkı sağlar.
Sürdürülebilirlik İçin DRY, KISS ve SOLID Prensiplerinin Birlikteliği
Kod tekrarını önlemek, tek başına projenin mükemmel olacağı anlamına gelmez. DRY prensibi, diğer yazılım tasarımı prensipleri olan KISS (Keep It Simple, Stupid - Basit Tut, Aptal Olma) ve SOLID prensipleriyle (özellikle Tek Sorumluluk Prensibi - Single Responsibility Principle - SRP) uyum içinde çalışmalıdır.
Örneğin, DRY prensibini uygulamak adına oluşturduğunuz ortak bir fonksiyon, zaman içinde farklı departmanların talepleriyle o kadar büyüyebilir ki, SOLID’in "S" (Single Responsibility) kuralını ihlal etmeye başlayabilir. Bir fonksiyon veya sınıf, yalnızca tek bir nedenden dolayı değişime uğramalıdır (yani tek bir sorumluluğu olmalıdır). Eğer DRY prensibini uygularken yazdığınız ortak sınıf; hem veritabanına yazıyor, hem e-posta gönderiyor, hem de loglama yapıyorsa, bu yapı sürdürülebilir olmaktan çıkar.
Aynı şekilde, kod tabanını tekilleştireceğim derken aşırı soyutlama yapıp okunabilirliği yok etmek KISS prensibine ayar verir. Kodun en iyi hali, bir sonraki yazılımcının ek bir açıklamaya gerek duymadan kodu rahatça okuyup anlayabileceği basitlikte olandır. Dolayısıyla, DRY ve KISS arasında her zaman hassas bir denge kurulmalıdır. Yinelenen kodları azaltırken, sistemin genel basitliğini ve okunabilirliğini feda etmemelisiniz.
Temiz Kod ve Düşük Bakım Maliyeti İçin Sürdürülebilir Yazılım Stratejileri
Kurumsal ölçekteki dijital ürünlerin yaşam döngüsü boyunca temiz kod yapısını korumak, sadece yazılımcıların inisiyatifine bırakılamayacak kadar stratejik bir konudur. İşletme yöneticileri ve teknik liderler, kod kalitesini sürekli kılacak kurumsal standartlar ve otomasyon süreçleri inşa etmelidir.
Bu süreçteki en etkili adımlardan biri, CI/CD (Sürekli Entegrasyon / Sürekli Dağıtım) süreçlerine statik kod analizi (static code analysis) araçlarının dahil edilmesidir. SonarQube, ESLint, ArchUnit veya CodeClimate gibi gelişmiş araçlar, her kod tesliminde (commit) projeyi tarayarak tekrarlanan kod bloklarını (code duplications), teknik borç oranını ve kod kokularını (code smells) otomatik olarak raporlar. Belirlenen kalite eşiklerini (Quality Gates) geçemeyen kodların ana sunucuya birleştirilmesi engellenerek, teknik borcun birikmesinin önüne geçilir.
Ayrıca, ekipler içinde güçlü bir akran denetimi (Peer Code Review) kültürü oluşturulmalıdır. Her birleştirme isteği (Pull/Merge Request) en az bir veya iki deneyimli geliştirici tarafından gözden geçirilmeli; DRY, SOLID ve KISS prensiplerine uyum titizlikle denetlenmelidir. Bu yaklaşım, sadece kodun kalitesini artırmakla kalmaz, aynı zamanda ekip içindeki bilgi paylaşımını ve teknik standart birliğini de üst seviyeye çıkarır.
Yazılım geliştirme hızını artırmak ile kod kalitesini korumak arasındaki dengeyi doğru yönetmek, projenin toplam sahip olma maliyetini (TCO - Total Cost of Ownership) düşüren en temel etkendir. DRY prensibine yapılan her yatırım, gelecekte yapılacak olan bakım, hata giderme ve yeni özellik ekleme maliyetlerinden devasa tasarruflar olarak kurumlara geri dönecektir.
Sıkça Sorulan Sorular
DRY prensibi sadece kod satırlarının birebir aynı olmamasını mı ifade eder?
Hayır, DRY prensibi kod satırlarının benzerliğinden ziyade sistem içindeki bilginin, iş kurallarının ve mantıksal süreçlerin tek ve kesin bir kaynağa (SSoT) sahip olması gerektiğini savunur.
WET kod yazmanın işletmelere maliyeti nedir?
WET kod tasarımı, teknik borcu artırarak hata ayıklama süreçlerini uzatır, birim testlerin bakım maliyetini katlar ve siber güvenlik açıklarının kapatılmasını zorlaştırarak toplam proje bütçesini şişirir.
DRY prensibini uygularken ne zaman durmalıyız?
"Üçler Kuralı" (Rule of Three) doğrultusunda, bir iş mantığı en az üç kez tekrarlanana kadar beklemeli, erken soyutlama yaparak sistemi gereksiz yere karmaşıklaştırmaktan kaçınmalıyız.
Yanlış soyutlama (wrong abstraction) ne anlama gelir?
Yanlış soyutlama, sadece tesadüfen birbirine benzeyen ancak farklı iş birimlerine ve gelecek senaryolarına sahip olan süreçlerin aceleyle tek bir ortak fonksiyona bağlanması hatasıdır.
Kod inceleme (Code Review) süreçlerinde DRY nasıl denetlenir?
CI/CD hatlarındaki otomatik statik analiz araçları (SonarQube vb.) ve geliştiricilerin gerçekleştirdiği manuel akran denetimleriyle tekrarlı yapılar tespit edilerek refactoring için yönlendirme yapılır.
DRY ve KISS prensipleri birbiriyle çelişir mi?
Bazen çelişebilir; kod tekrarını önlemek için tasarlanan aşırı genel (generic) ve karmaşık soyutlamalar kodun okunabilirliğini yok edebilir. Bu durumlarda basitlik (KISS) korunarak pragmatik bir denge kurulmalıdır.
Mikro servis mimarilerinde DRY nasıl uygulanır?
Mikro servislerde DRY, servisler arası ortak kullanılan mantıkların (ör. loglama, yetkilendirme) merkezi API Gateway, paylaşılan ortak kütüphaneler (shared libraries) veya servis şablonları üzerinden dağıtılmasıyla sağlanır.
Kod içinde sihirli sayılar (magic numbers) kullanmak DRY prensibine aykırı mıdır?
Evet, sistem genelinde sabit değerlerin (dosya boyutları, timeout süreleri vb.) kod tabanına statik olarak yazılması DRY ihlalidir; bu değerler tek bir yapılandırma dosyasından yönetilmelidir.