Temiz Kod, Yazılım Tasarımı ve Test

Değiştirilebilir yazılım üretmeyi; sorumluluk, coupling, cohesion, refactoring ve test piramidi üzerinden öğrenin.

Çalışan koda küçük bir özellik eklemek günler sürüyorsa problem çoğu zaman sözdizimi değildir. Sorumluluklar birbirine karışmış, davranış testlerle korunmamış ve değişiklik etkisi öngörülemez hâle gelmiştir.

İyi tasarım neyi optimize eder?

Cohesion, bir modülün içindeki parçaların aynı amaca hizmet etme derecesidir; yüksek olması istenir. Coupling, modüllerin birbirine bağımlılığıdır; gereksiz olanı azaltılır. Abstraction, ayrıntıyı saklayıp ihtiyaca uygun bir arayüz sunar. Encapsulation, veriyi ve geçerli değişiklik yollarını aynı sınırda korur.

function calculateTotal(items: Item[]): Money {
  return items.reduce((total, item) => total.add(item.price), Money.zero());
}

Fonksiyon adı niyeti açıklar. Parametre bağımlılığı görünür yapar. reduce, öğeleri tek toplam değerde birleştirir. Money türü para aritmetiği ve para birimi kurallarını merkezileştirebilir. Ancak tek satır olmak otomatik olarak temiz kod değildir; ekip için anlaşılır olması gerekir.

Test türleri

Unit test küçük davranışı hızlı ve izole doğrular. Integration test veritabanı veya servis sınırlarının birlikte çalışmasını sınar. End-to-end test kullanıcı akışını bütün sistem üzerinden kontrol eder. Çok sayıda hızlı unit/integration testi ve az sayıda kritik E2E testi dengeli bir yapı sağlar.

Test uygulama detayını değil davranışı korumalıdır. Refactoring, programın dışarıdan görülen davranışını değiştirmeden iç yapısını iyileştirmektir. “Özel metod üç kez çağrıldı” testi refactoring’de kırılabilir; “sepette iki ürünün toplamı doğru” testi gerçek sözleşmeyi sınar.

Refactoring akışı

Önce mevcut davranışı testle güvenceye alın. Küçük değişiklik yapın. Testleri çalıştırın. Tasarım değişikliği ile yeni özelliği mümkün olduğunca ayrı adımlarda tutun. Bu döngü hata kaynağını daraltır.

Alternatifler ve denge

Her fonksiyon için interface, yani uygulamanın nasıl yapıldığını değil dışarıya hangi işlemleri sunduğunu tanımlayan sözleşme üretmek gereksiz soyutlama oluşturabilir. Tek uygulaması olan ve değişmesi beklenmeyen ayrıntıyı doğrudan kullanmak daha anlaşılır olabilir. Kod tekrarının aynı görünmesi, aynı nedenle değişeceği anlamına gelmez. Tasarım desenini isim olsun diye değil tekrarlanan değişiklik baskısına cevap olarak kullanın.

Kontrol listesi

  • Bir modülün değişmesi için bir ana neden var mı?
  • İş kuralları framework kodundan ayrılabiliyor mu?
  • Test başarısız olduğunda neden anlaşılabiliyor mu?
  • Bağımlılıklar constructor veya parametrelerde görünür mü?
  • Soyutlama bugünkü problemi mi, hayal edilen geleceği mi çözüyor?