Kendini tekrar etme! DRY prensibi kodun tekrarlanmasına (code duplication) düşmandır. Aynı işi yapan kodların (genellikle kopyala-yapıştır ile) ihtiyaç duyulduğu her yerde tekrarlanarak projenin çöp olması; yönetilebilirlik, haliyle geliştirilebilirlik ve sürdürülebilirlik imkanlarından gittikçe uzaklaşmasını engellemeye odaklanır.
Eğer daha önce yazılmış bir kod ya da kod bloğunu tekrar kullanmaya ihtiyacımız olursa; mevcut kodu bir fonksiyona/sınıfa/metoda dönüştürerek (mümkünse refactor ederek) eski kullanan yeri bu noktaya bağlayıp, sonrasında yeni yazacağımız kodlarda da bu merkezileştirdiğimiz nokta üzerinden kullanmalıyız.
Bu prensip ile biz yazılımcıların çok hoşuna giden “çalışıyorsa kurcalama” atasözüne ters davranacağız. Başlangıçta konfor alanımızdan çıkmamıza zorlayacak, hoşumuza gitmeyecek fakat zamanla alışacak ve faydalarını tecrübe ettikçe kendinizi geçmişte yazdığınız tekrarlayan kodlarınız için pişmanlık hissederken bulacaksınız 🙂
Şimdi biraz örnekler üzerinden ilerleyelim. Öncelikle bu prensibin dikkate alınmadığı (kötü) örneği ve dezavantajlarını inceleyeceğiz;
Bu örnekte Cart ve Checkout sınıflarında kullanıcı kredisini +1000 olacak şekilde manipüle ediyoruz. Bu manipülasyonun daha birçok yerde tekrarladığını düşünün ve sonra bir gün artık +1000 değil -250 olarak güncellenmesi gerektiğini düşünün ve sadece şu iki soruyu yanıtlayalım;
- Bu kuralın geçerli olduğu yerleri bulmak için proje kaynak kodlarında nerelerde +1000 geçiyor diye mi bakacaksınız? (Ya +1000 şeklinde arama yaptığınızda projenizde 300 dosya çıkarsa?)
- Hadi tertipli geliştirilen bir proje olduğunu düşünelim ve GetUserCredit’i arayıp bulduğunuz her yerde +1000’i -250 olarak mı güncelleyeceksiniz? (Ya değiştirmeyi unuttuğunuz/atladığınız bir yer olursa?)
Bu gibi gereksiz heyecanları yaşamamak ve ruhsal sağlığımızı korumak adına 1000 rakamını merkezileştirebiliriz değil mi? Evet, bunu bir constant vs. çekerek 1000 rakamını kolayca değiştirebiliriz ama ya formülün değişmesi gerekirse? Bu seferde tek tek 1000 değerini güncellemek yerine gidip formülü mü güncelleyeceğiz? HAYIR
Peki DRY prensibini dikkate aldığımızda bu kod nasıl olurdu?
Neler değişti?
Kredi bilgisi dönen metodlardaki manipülasyon işlevlerini UserHelper.GetUserCredit içerisine taşıdık, bu sayede manipülasyon formülünü değiştirmemiz gerekirse sadece UserHelper.GetUserCredit gövdesini değiştirmemiz yeterli olacak. Sonra bu işleve ihtiyaç duyduğumuz her yerde UserHelper.GetUserCredit üzerinden kullandık.
DipNot: En iyi pratikte (best practice) zaten kullanıcı kredisi; adı User olması gereken sınıfın GetCredit metodundan almak Cart ve Checkout içerisinde bunun için bir metod olmaması gerekir. Yani bu örneği bir iterasyon daha da iyileştirmek istediğimizde tüm bu işlevleri User sınıfı altında toplardık.
İlk örnekte geliştirme zorlukları yaşarken DRY prensiplerine uygun geliştirme yaptığımızda psikolojimizin bozulmadığını ve projede geliştirme yaparken gerilimin yerini keyife bıraktığını görmüş olduk.
Kendinizi ya da başkalarını tekrarlamadığınız temiz kodlar yazdığınız ve böyle yazılmış projelerde geliştirme yapmanız dileğiyle…