4 puan yazan GN⁺ 2023-12-09 | 1 yorum | WhatsApp'ta paylaş
  • Bir grafik editöründeki yeniden boyutlandırma kodunu tekrarları kaldırma odağıyla yeniden yazıp sonra geri almak zorunda kalma deneyimi üzerinden, Clean Code takıntısının gerçek değiştirilebilirliği zedeleyebileceğini gösteriyor
  • Mevcut uygulamada Rectangle, Oval, Header ve TextBlock için tutamaçlara göre formüller tekrarlanıyordu; yeni uygulama ise yönleri ve şekilleri ayırıp birleştirerek tekrarı ortadan kaldırmaya çalışıyordu
  • Refactoring’in hemen ardından kod boyutu yarıya inmiş ve değişiklik noktaları tek yerde toplanmıştı; ancak sonrasında şekle ve tutamaca özgü özel davranışlar gerektiğinde soyutlama tam tersine engel olabilirdi
  • Teknik karardan daha büyük sorun, asıl kodu yazan ekip arkadaşıyla görüşmeden değişikliği doğrudan master’a check-in etmekti; bu, ekibin güven inşa etmesine zarar verebilir
  • “Temizlik” bir hedef değil, karmaşık sistemlerle başa çıkmak için yalnızca bir araçtır; kodun görünümünden çok, ekibin birlikte değişime yanıt verebilmesi daha önemlidir

Grafik editöründe yeniden boyutlandırma kodundaki tekrarlar

  • Grafik editörü canvas’ında, dikdörtgen ve elips gibi şekilleri kenarlardaki küçük tutamaçlarla yeniden boyutlandıran bir kod vardı
  • Uygulama çalışıyordu, ancak şekil ve tutamaç yönü başına konum ve boyutu hesaplayan formüller tekrarlanıyordu
    • Rectangle, resizeTopLeft, resizeTopRight, resizeBottomLeft, resizeBottomRight gibi metotlara sahipti
    • Oval, resizeLeft, resizeRight, resizeTop, resizeBottom gibi metotlara sahipti
    • Header ve TextBlock da kendi yeniden boyutlandırma metotlarına sahipti
  • Kullanıcı Shift’e bastığında yeniden boyutlandırma sırasında oranı korumayı da ele almak gerekiyordu; bu da formüllerin daha da çoğalmasına yol açıyordu

Tekrarı kaldırmak için soyutlama

  • Tekrar iki eksende görünüyordu
    • Aynı yöndeki tutamaçlar arasında tekrar vardı: Oval.resizeLeft() ve Header.resizeLeft() ikisi de sol tutamacı sürükleme davranışıydı
    • Aynı şeklin içindeki metotlar arasında tekrar vardı: Oval içindeki çeşitli metotların hepsi elipsle ilgileniyordu
  • Yeni yapı, kodu Directions ve Shapes olarak ayırıp yöne göre davranışı ve şekle göre davranışı birleştirmeye çalışıyordu
    • Directions içinde top, left, bottom, right yer alıyordu
    • Shapes içinde Oval, Rectangle yer alıyordu
    • createHandle, createBox ile tutamaçlar ve şekiller birleştiriliyordu
  • Bu yaklaşımda fourCorners, fourSides, twoSides gibi tutamaç yapılandırmaları oluşturuluyor ve bunlar kullanılarak Rectangle, Oval, Header, TextBlock üretiliyordu

Refactoring sonrasındaki yanılsama

  • Refactoring’den sonra toplam kod boyutu yarıya indi ve tekrar ortadan kalkmış gibi görünüyordu
  • Belirli bir yönün veya şeklin davranışı değiştirileceğinde birden fazla metot yerine yalnızca tek bir yerin düzenlenmesinin yeterli olacağı düşünülüyordu
  • Gece geç saatte değişiklik master’a check-in edildi ve ekip arkadaşının dağınık kodunun temiz biçimde çözüldüğü sanıldı

Ertesi gün ortaya çıkan sorun

  • Ertesi gün yönetici değişikliğin geri alınmasını istedi; o sırada yeni kodun mevcut koda göre daha temiz olduğuna inanıldığı için bunu kabullenmek zordu
  • Zaman geçince bu kararın iki nedenle doğru olduğu anlaşıldı
    • Asıl kodu yazan kişiyle konuşmadan kod yeniden yazılıp check-in edilmişti
    • Tekrarı azaltmanın karşılığında gereksinim değişikliklerine uyum kolaylığı feda edilmişti
  • Sağlıklı bir mühendislik ekibi sürekli güven inşa etmelidir; ekip arkadaşının kodunu geniş çapta yeniden yazmak iş birliğine büyük darbe vurabilir

Yanlış soyutlamanın maliyeti

  • Daha sonra birçok şeklin birçok tutamacı için çok sayıda özel durum ve davranış gerekti
  • Yeni soyutlama yapısında bu gereksinimleri karşılamak kodu birkaç kat daha karmaşık hale getirebilirdi
  • Buna karşılık, asıl “dağınık” yapıdaki her metot ayrık olduğundan bu tür değişiklikleri uygulamak görece daha kolaydı
  • Kod tekrarını kaldırmak bedava değildir; bir yetenek kazanırken başka bir yeteneği kaybedebilirsiniz

“Temizliği” yeniden düşünmek

  • “Clean Code” ve tekrarları kaldırma takıntısı, birçok geliştiricinin yaşayabileceği bir dönemdir
  • Kendi yazdığı koda güveni az olduğunda, katı lint kuralları, adlandırma kuralları, dosya yapısı ve tekrar olmaması gibi ölçülebilir şeylerle gurur duymak kolaydır
  • Soyutlama yapmayı öğrendiğinizde, tekrar eden kod gördüğünüz her seferinde soyutlamanın bir erdem olduğuna inanıp bunu uygulamak isteyebilirsiniz
  • “Temiz” ya da “kirli” hissinin gerçekte hangi mühendislik sonuçlarıyla bağlantılı olduğunu derinlemesine düşünmek gerekir
  • Önemli olan yalnızca kodun nasıl göründüğü değil, ekibin insanlarıyla birlikte kodun nasıl değiştiği ve düzeltildiğidir

Clean Code’u bırakmak gerektiğinde

  • Clean Code bir hedef değil, karmaşık sistemleri anlamaya yönelik bir girişimdir
  • Kod tabanında bir değişikliğin ne etki yaratacağından emin olunmadığında yön gösteren bir savunma mekanizması olabilir
  • Başta fonksiyon çıkarma veya sınıf refactoring’iyle karmaşık kodu basitleştirme deneyimi keyifli gelebilir
  • Ancak orada durup “Clean Code fanatiği” haline gelmemek gerekir
  • Clean Code’un rehber olmasına izin verin, ama bir noktada onu bırakmak gerekir

1 yorum

 
GN⁺ 2023-12-09
Hacker News yorumları
  • Kod tekrarı bazen sorun olmayabilir, ama bu Clean Code’un kötü olduğunun kanıtı değildir
    Refaktöring biraz fazla ileri götürülmüş gibi; “tekrarlanan 10 satırlık matematik”i bir fonksiyona çıkarmakla yetinilseydi daha temiz olurdu
    O 10 satırı fonksiyona dönüştürmeyen ekip arkadaşı da pek iyi iş çıkarmamış; ben olsam PR’ı reddederdim ama kendim baştan yazmazdım
    Başkasının PR’ını baştan yazmak, tartışma alanını kapatan hızlı bir hakarettir; çoğu zaman kodun neden öyle yazıldığı bağlamı da bilinmez
    Kodlama standartları yoksa PR incelenip reddedilmelidir; “Clean Code önemli değil” diye commit edilmesine izin verirseniz, birkaç ay içinde kimsenin çalışmak istemeyeceği bir kod tabanına dönüşür
    Buradan çıkarılacak ders Clean Code değil, iletişim ve nezakettir

    • Başkasının çalışan kodunu bizzat baştan yazmak yalnızca yazarı aşağılamak değil, bakımı başka birine ait olan kodu değiştirerek zaman harcayan profesyonellik dışı bir davranıştır
      Asıl yazarın, düşük kaliteli kodun pratikte zamanı nasıl boşa harcadığını öğrenme fırsatı da ortadan kalkar
      Clean Code yaklaşımı daha iyi olsa bile, buradaki asıl mesele kod değil; faydalı geri bildirim vermeden kendi zamanını boşa harcamaktır
      En iyisi, asıl yazarın çıtayı yükseltmesi ve kişinin gerçekten ilgilenmesi gereken başka işleri yapmasıydı. Yani doğru cevap kod incelemesiydi
    • Ders daha çok “bağlama göre ödünleşimleri düşünmeden kuralları aşırı uygulamayalım” şeklinde; bu da öğrenmesi zaman alan bir ders
    • 20 yılı aşkın süredir gördüğüm kadarıyla, “tekrarlanan 10 satırı fonksiyona çıkarmadığına göre berbat” düşüncesi genellikle kod tabanında yanlış şeye odaklanan insanlarda sık görülür
      Bu kişiler gerçek sorunları çözmek yerine sorun olmayan şeyleri çözerken geleceğin sorunlarını da yaratırlar
      İlk uygulamada, böyle 10 satırlık çok küçük bir kodu soyutlamamak genelde daha doğrudur. Tam olarak o işi yapan kodu daha sonra değiştirmek kolaydır; kanıtlanmamış bir fayda için 10 satırı soyutlamanın anlamı azdır
      Clean Code hiç önemli değildir; benzer kuralların ya da “ilkelerin” çoğu da önemli değildir. Aksine, zamanla kod tabanında arı peteği gibi yapılar biriktirip bunu meşrulaştırmaya çalışan insanların tutunduğu şeylerdir
      Sonuçta aşırı soyutlanmış, değiştirmesi zor, yavaş ve anlaşılması güç kod ortaya çıkması kolaydır
      Bir ilke gerekiyorsa, programın gerçekte yaptığı iş olan veri dönüşümünü açık ve kolay değiştirilebilir biçimde ifade etmeye bakmak yeterlidir
      SOLID ilkelerinin çoğu, veri dönüşümünün ne olduğunu ve nasıl gerçekleştiğini görmeye yardımcı olmaz; hatta çoğu zaman engel olur. Bu yüzden gerçek programları anlamada genellikle pek işe yaramazlar
    • Orijinal yazının ifade biçiminin iyi olmadığını düşünüyorum
      Önerilen refaktöringe bakınca o 10 satır aslında aynı değil, yalnızca benzerdi
      Bir dikdörtgenin sol üst köşesini yeniden boyutlandırma formülü ile bir elipsin sağ altını değiştirme formülü farklıdır. Dışarıdan benzer görünürler ama bazı yerlerde + yerine - vardır
      Bu durumda karmaşıklık geometrinin kendisindedir; bunu “soyutlamak” dağınıklığı yalnızca başka bir yere taşır, temelde ortadan kaldırmaz
      Özel bir sayı sistemi gibi akıllıca matematiksel soyutlamalar mümkün olabilir; ancak dilde yerleşik değilse, temel tamsayılarla özel işlemler uygulamanın maliyeti büyük olasılıkla sağlayacağı kazançtan fazla olur
  • “Clean Code”un yeniden markalanmaya ihtiyacı var
    25 yılı aşkın kariyerim boyunca tasarım kalıpları, soyutlama, tekrarın giderilmesi gibi konulara yönelik bitmeyen tepkiler gördüm
    Sürekli öne sürülen gerekçeler şunlar: soyutlama kodu daha karmaşık hale getirir, Clean Code yazmaya zaman yoktur, hepsi zevk ve görüş meselesidir
    Oysa Clean Code’un amacı, gereksinimler değiştiğinde kodu daha basit ve bakımı daha kolay hale getirmektir
    Yazılımın değeri, zamanla değişebilmesindedir. Aksi halde uygulanması ve bakımı çok daha kolay ve ucuz olan sabit devreler kullanırdık
    Refaktöring bu hedefe ulaşmadıysa ve yöneticisi, gelecekteki gereksinim değişiklikleri karşısında bakımının daha zor hale geldiğini ikna edici biçimde söyleyebiliyorsa, o kod “temiz” değildi
    Asıl yazarla tartışmamak, Clean Code kapsamının dışında kalan bir süreç ve görgü meselesidir. Kaba ve tek taraflı davranılmış olması Clean Code’un değerini ortadan kaldırmaz

    • Tepkinin, fazlasıyla mutlak reçetelere yönelik olduğunu düşünüyorum
      Ünlü Clean Code kitabı, “tekrar olmaması”nı iyi tasarlanmış bir sistemin koşulu olarak sunar ve tekrarı ek işin, ek riskin ve gereksiz karmaşıklığın baş düşmanı olarak görür
      Bu tanıma göre tekrarı gidermek sadeleştirmeyle eşanlamlı hale gelir; bu yanlıştır
      Tekrarı gidermek, bağımlılık getirmektir. Bu bağımlılık problemi iyi modelliyorsa iyi bir soyutlama ve sadeleştirme olabilir; değilse soyutlama kılığına girmiş sıkıştırmadan ibarettir
      Bu alıntının, Clean Code’da geçen Kent Beck’in Simple Design bahsinden olduğunu not düşeyim
    • “Clean Code” iki anlamda kullanılıyor
      Biri bir kodun iyi olduğuna dair öznel his; diğeri ise Clean Code kitabını ve ilgili yönergeleri izlemek
      Giderek daha fazla insan bu ikisinin büyük ölçüde farklı olduğunu düşünüyor. Kitaptaki bazı yönergeleri izlemek, aksine hiç de temiz olmayan kodlar ortaya çıkarabiliyor
      İdeal bir dünyada herkes temiz kod yazmak isterdi; ancak Clean Code’un bu hedefe ulaşmak için iyi bir yol olduğunu düşünenlerin sayısı azalıyor
      Özellikle aşırı soyutlama ve tekrarın giderilmesi, birçok kişi tarafından dağınık kodun kaynağı olarak görülmeye başladı
    • Sektörde öğrendiğim şey şu: En temiz yazılmış kod bile ürün gereksinimleriyle karşılaşınca uzun süre dayanamaz
      Bazen teknik borç, ürün gereksinimlerinin içine kodlanmış haldedir; refaktöring ya da iyi uygulamalarla düzeltilemez, yalnızca acısı azaltılabilir
    • “Gerçek İskoç bu değildir” türü bir mantık gibi geliyor
      Clean Code’un amacı ile pratikteki sonuçları arasında büyük fark var. Çünkü insanlar, gereksinimler gözlerinin önünde olsa bile kodun gelecekteki halini çoğunlukla öngöremez
      Clean Code, “ya şöyle olursa?” gibi korkunç bir soruyu davet eder; bu da sürümü sonsuza dek erteleyen bir Pandora kutusuna kolayca dönüşür
      Neredeyse her zaman bildiğinize göre kodlamak ve mimariye alan deneyimi olan birinin yön vermesi daha iyidir
    • Alternatifleri sıralamak gerekirse, yaptığımız soyutlamaların çoğu kötüdür; iyi olduğunu düşündüklerimiz bile genellikle öyledir
      İyi soyutlamaların önemli bir kısmı zaten kütüphanelerde bulunur. Elbette ne yazık ki bu her zaman böyle değildir
      Kötü soyutlama zaman yer; kod aynı zamanda ekipteki diğer insanlarla iletişim kurma işidir, bu yüzden benim düşünme biçimimden çok ekip arkadaşlarının bu iletişimi nasıl algıladığı önemlidir
  • Bir ekip arkadaşınız kopyala-yapıştırla çok kod yazmış, siz de commit’ten sonra refactor etmişsiniz
    Ekip arkadaşınız yöneticiye şikâyet etmiş, yönetici de sizi azarlamış; sonuçta bir dahaki sefere kod tabanında dağınıklığı bırakacağınıza karar vermişsiniz
    Buradan çıkarılacak dersler var ama bu, kopyala-yapıştırın fonksiyon yazmaktan daha iyi olduğu anlamına gelmez
    Refactor, asıl yazarı etiketleyen ayrı bir değişiklik olarak açılıp incelemeye sunulmalıydı
    Yine de ekip arkadaşının doğrudan konuşmak yerine konuyu yöneticiye taşıması ve yöneticinin geri almanızı istemesi oldukça kötü bir işaret

    • Ben olsam ekip arkadaşıma Slack’ten özel mesaj atıp “Bu fonksiyonların her birinde 10 satırlık matematik tekrarlanıyor; bunu ayrı bir fonksiyona çıkarmak daha iyi olmaz mı?” diye sorardım
      Olası cevap ya “Hayır, çünkü…” ya da nadiren “Haklısın, yarın yaparım” olurdu
      Gürültü çıkmadan herkes sorundan kaçınır, birileri de bir şeyler öğrenebilir
    • Tembelce yapılmış kopyala-yapıştır söz konusuysa, tekrar için fonksiyon kullanmak, yani soyutlama yapmak DRY açısından daha iyidir
      Ancak yazar önemli bir bağlam eklemiş. Gereksinimlerin değişebilme olasılığını tekrarları azaltmakla takas etmiş ve sonradan her şekle ait tutamaç için pek çok özel durum ve davranış gerekmiş
      Bu, tesadüfi DRY ile özsel DRY arasındaki farkı gösteriyor
      A ve B kütüphaneleri birbirleriyle tutarlı göründüğü için kodun aynı hale gelmesi sık yaşanır; ama gerçekte bu bir tesadüf olabilir
      lib A’yı saran wrapper ile lib B’yi saran wrapper aynı kodu içeriyor olsa bile, tamamen farklı şeyleri sarıyorlarsa bunları soyutlamak kötü sonuç verir
      “15” için de aynı şey geçerli. “Tüm listeler her zaman 15 öğe göstermeli” ise 15’i soyutlamak doğru olur; ama “ana sayfadaki en iyi 15 şarkı” ile “şarkı altındaki varsayılan 15 yorum” ayrı şeylerse, o 15’leri birbirine bağlamak daha kötü bir seçimdir
    • En büyük tehlike işareti, ekip arkadaşının katkısını hiç iletişim kurmadan değiştirmiş olmanız
      İkinci tehlike işareti ise refactor’ın kendisinin de iyi bir refactor olmaması. Modülerlik eksik, hâlâ bağlılık var; yalnızca tekrarlar biraz azaltılmış
    • Asıl yazarı etiketlemek de sorun çıkarabilir
      “Yazdığın kod pek iyi değildi, ben yeniden yazdım. İtirazın mı var?” gibi duyulabilir
      En iyi çözüm muhtemelen “geç kalmış inceleme” biçiminde açıklama istemek, bir çözüm önermek ve asıl yazarın bunu öylece görmezden gelmemesini ummak olurdu
    • Yazının sonunda, daha sonra kod tabanında yapılan değişikliklerde şekle özgü tutamaçların özel olarak ele alınması gerektiği; bunun refactor edilmiş yapıda zor, tekrarlı kodda ise kolay olduğu önemli bir bölüm vardı
      Esas nokta, kodun gelecekte değişeceğini kabul etmek. Gereksinimler de değişir, ilgili kod da değişir
      Bu değişebilme kabiliyetini sınırlayan bir soyutlama yaparsanız, gelecekteki benliğinizin kod tabanını uyarlama yeteneğine zarar verirsiniz
      Özellikle çok zaman ve emek harcanmış soyutlamalara duygusal olarak bağlanıp, değişimi zarif çözüme uydurmaya çalışırken daha fazla zaman da harcayabilirsiniz
      KISS doğru yaklaşım
  • Bu örnek daha çok “kimse ukalaları sevmez” meselesi gibi görünüyor
    Özellikle junior geliştiriciler, işin yalnızca kendileriyle bilgisayar arasında değil; kendileri, bilgisayar ve diğer insanlar arasında olduğunu henüz öğrenmemişken sık yaşanır
    Daha temiz sürüm, asıl yazarla gerçekten konuşulup daha iyi bir yöntem üzerinde anlaşılmış olsaydı büyük olasılıkla kabul edilirdi
    Yazının başlığı “Hoşça kal, temiz kod”dan çok takım içinde çalışmayı öğrendim olmalıymış gibi görünüyor

    • “Kimse ukalaları sevmez” ifadesi geliştirme ortamını iyi yakalıyor
      Daha karmaşık kod bir tehdit olarak algılanmış ve yönetim zinciri üzerinden bastırılması gereken bir rakip gibi görülmüş olabilir
      Junior iseniz bu sözün bağlama bağlı olduğunu bilmelisiniz. Pek çok iş yerinde basitlik esneklikten daha önemlidir; kafa karıştıran dil özelliklerinden kaçınılır, klavye başında uzun süre geçirten çalışma biçimleri ve bu tür diller tercih edilir
      Buna karşılık yaşam boyu öğrenmeyi, yazılım zanaatkârlığını ve süreç üzerine düşünmeyi önemseyen felsefeler böyle ortamlarla tamamen çatışır
      Daha iyi olmaya çalışmak, gelişmeyen insanlar arasında popüler değildir
      İkisi de geçerli yaşam tercihleridir. Yazılım, 7 saat çalışıp eve gitmenin rahat olduğu bir yer de olabilir; hayal gücü ve zekânın tek sınır olduğu bir keşif dünyası da
      Yeni şeyler keşfetmek istiyorsanız, bilinmeyenden korkan insanlarla onlarca yıl geçirmeye dikkat etmelisiniz
      Daha kısa söylemek gerekirse, ekip arkadaşlarınızla teşvikleriniz uyuşmuyorsa ayrılmayı düşünmelisiniz
    • Başlığın iyi olduğunu düşünüyorum
      Bu yazının uzun süre sevilmeyi hak eden nedenleri var ve aynı tuzağa düşen birçok geliştiricinin gözünü açtı
      Tek başınıza çalışıyor olsanız bile temiz bir soyutlamayı fazla tasarlayıp gelecekte o soyutlama tarafından ısırılabilirsiniz
    • Bu tür sorunları genelde junior’lardan çok, gücün sarhoş ettiği senior’lar daha sık yapar
  • Sorun, değişikliğin inceleme olmadan doğrudan main branch’ine commit edilmesinde
    İster pair programming ister geleneksel PR olsun, tüm kod değişikliklerinde ekip arkadaşlarından inceleme olmalı ki bu tür tırmanmalar önlenebilsin
    Yönetici kötü bir yöneticiydi. Azarlamak yerine iyi bir sürecin eksik olduğunu fark etmeliydi
    Kod inceleme kültürü olan bir ekipte, hevesi fazla kaçmış yeni bir çalışan böyle bir şey denese bile ekip arkadaşı “Teşekkürler ama bu olmaz” ya da “İyi fikir, şöyle deneyelim” derdi
    Ayrı olarak, iyi bir sebep olmadan kodu refactor etmemek gerektiğini düşünüyorum. Kötü kod bile neredeyse hiç değiştirilmesi gerekmeyen kod olabilir
    Refactor için en iyi zaman, davranışı değiştirmeniz gerektiğinde mevcut yapının bunu çok zorlaştırdığını fark ettiğiniz andır
    Ne yazık ki burada yanlış ders çıkarılmış gibi görünüyor

    • Birleştirmeden sonra yapılan kod incelemesi de tamamen gayet iyi, hatta bazı açılardan daha iyi
  • Neden herkesin yalnızca onun bunun yerine ne yapması gerektiğini söylediğini anlamıyorum. Bu gayet meşru bir ders
    Finansta sürekli bir ölçüde benzer ama tamamen aynı olmayan ürünlerle uğraşırsınız. Hisse senedi opsiyonları ve döviz opsiyonları ikisi de opsiyondur, kullanım fiyatları vardır ve Black-Scholes’ın bir sürümüyle fiyatlanırlar; ama pratikte inanılmaz derecede farklıdırlar
    Ekibe yeni katılan birinin birçok davranışı ortaklaştırmak istemesi büyük bir cazibedir ve biz de sık sık özgün yazıdaki yöneticinin konumunda, genç geliştiriciye sakin olmasını ve bunları ayrı tutmasını söyleriz
    Bu, temiz koda veda etmek değil; gerçekten temiz kodu koruyabilmek için aşırı soyutlamadan kaçınmak gerektiği anlamına gelir

    • Finans örneği doğru, ama burada geometriyle uğraşılıyor
      Genel bir tutamacın yaptığı şey afin dönüşümdür; yani öteleme, döndürme, ölçekleme ve yansıtma. Tekdüze ölçeklemeyse benzerlik dönüşümüdür. Bunun her şekil üzerinde çalışacağı garanti edilir
      Asıl sorun, yeterince bilmediğiniz şeyi soyutlamamanız gerektiğidir. Özellikle de gelecekte hangi olasılıkların doğacağını bilmiyorsanız
      Örneğin ovalin sadece daire ve elipsten ibaret olduğunu düşünürseniz, ilk “gerçek” oval ortaya çıktığında epey şaşırırsınız
    • Yazının ana fikrini anlıyorum, ama başlık gerçekten dağınık kodu meşrulaştırmak için bir bahane gibi kolayca okunabiliyor
      Yazar dağınık kod ile “temiz olmayan” kodu aktif biçimde ayırmadığı için başkaları ayırmaya çalışıyor
    • Buradaki herkesin, birkaç satır sözde kod dışında bağlamı olmamasına rağmen o zamanki ekip üyelerinden ve yazardan daha iyi bildiğini hissettiği oldukça belli oluyor
      DRY değerlidir, ama soyutlamanın bir maliyeti vardır. Bu her zaman bir ödünleşimdir
  • Haskell gibi dilleri sevmemin nedenlerinden biri, soyutlama maksimalizminin kodlama düzeyinde değil, dil düzeyinde yerleşik olması
    Applicative’in ne yapması gerektiği konusunda herkes hemfikirdir. Zorluk, fikirden koda giden hattın daha sağ tarafına, yani probleme uygun Applicative’i bulmaya kayar
    Nesne yönelimli tasarım desenlerinin çoğunun bu ortamda doğal ve iyi tanımlanmış karşılıkları vardır ve proje bazlı soyutlamaları azaltmaya yardımcı olur
    Yeni başlayanlar için dili öğrenmenin başlangıç maliyeti yüksektir; ayrıca başka bir Haskell kodu açıp ilk kez gördüğünüz yaklaşık 12 derleyici uzantısını anlamak zorunda kalmanız sık yaşanır
    Yine de o derleyici uzantılarını daha sonra tüm projelere taşıyabildiğiniz için bunu net kazanç olarak görüyorum
    Uzmanlar içinse cats’in ne kadar RAM yiyeceğine dair sezgi kazanmak için doktora gerekmesi gibi bir dezavantaj var

    • Applicative ve Monad’ın ne yaptığını bilmemizin nedeni matematiksel yasalar olmasıdır
      Bir kod Applicative ya da Monad kullanıyorsa, o yasalar sayesinde davranışını bilebilirsiniz
      Nesne yönelimli tasarım desenlerinde böyle yasalar yoktur. Gevşek tanımlı kavramlar ya da desenler oldukları için kişisel yoruma ve özelleştirmeye açıktırlar; ama tam olarak ne olduklarını ve hangi davranış ya da çıktının beklenmesi gerektiğini söyleyen somut yasalar yoktur
    • Bir Haskell kullanıcısı olarak dilin soyutlama gücünün çok iyi olduğuna katılıyorum
      Ancak blog yazısındaki örnek için, temiz kod yolunu izlerken gelecekteki kendinizi gerçekten çok kez ayağınızdan vurduğunuzu söylemek zorundayım
      Daha sonra tekrar anlamak için soyutlamayı çalışmanız gerekiyorsa, o soyutlama faydalı değildir
    • Özgün yazıda ekip genel olarak karşı çıkmadığı sürece nesne yönelimli ilkeleri daha fazla kullanmak daha iyi olurdu. Böyle bir ekipse ben olsam başka bir yerde çalışırdım
      Nesne yöneliminin en doğal uyduğu yer GUI widget’ları ve editör uygulamalarıdır
      Nesne yöneliminin diğer kurallarını birleştiren kural sorma, yaptır ilkesidir
      Bu örnekte tutamaçlar bilinen bir şekilde paylaşılır ve şekle özgü kontrol noktaları olurdu. Kutu tutamacı değiştiğinde updateControlPoints(changedHandle) çağrılabilir; kontrol noktası değiştiğinde de updateBoxHandles(changedControlPoint) çağrılabilir
      Başka temiz ayrımlar da mümkün olabilir, ama ben olsam böyle yapardım
    • Applicative’in ne yapması gerektiği konusunda anlaşabilirsiniz
      Ama hangi ayrıştırma kütüphanesinin kullanılacağı, Data.Text.Strict ile Data.Text.Lazy arasında hangisinin seçileceği, point-free stilin ne kadar kullanılacağı, . ile >>> veya başka birleştiricilerden hangisinin tercih edileceği, hangi dil uzantılarının kullanılacağı konusunda pek anlaşma olmaz
      Haskell’i seviyorum ama diğer dillere benzer sorunlar yaşıyor. İnsanlar iş yapmanın en iyi yolu konusunda gerçekten anlaşamıyor
    • Bir adım daha ileri gidip afin tipler kullanan Rust kullanabilirsiniz
      Haskell tip sistemiyle öngörülebilir performansı elde edersiniz
  • Yinelenen matematik kısmını ayrı bir fonksiyona taşıyıp, yeniden boyutlandırma fonksiyonundan çağırmak yeterli olurdu
    Yeniden boyutlandırma fonksiyonlarının kendisi tekrarlı görünüyordu çünkü bir arayüz oluşturuyorlardı; bu yüzden onu ortadan kaldıran refactoring yanlıştı
    Ama o fonksiyonların yaptığı matematik, kodu düzenlemek için tamamen geçerli bir hedefti

    • Evet. Bu bariz yön gibi görünüyor ve genelde ben de öyle yaparım
      Sonuçta küçük, saf fonksiyonlardan bir sürü oluşuyor; ama test etmesi ve refactor etmesi kolay olduğu için sorun olmuyor
    • Özellikle refactoring söz konusuysa, bir ekiple çalışırken bunu genellikle aşamalı ele almak daha iyidir
      Aynı problemi çözmenin birçok yolu ve deseni vardır; ama başkalarının kullandığı mevcut arayüzü söküp atmak iyi bir başlangıç değildir
      Soyutlamanın avantajı, geri kalanına zarar vermeden iç kısmı daha esnek biçimde değiştirebilmenizde yatar
      İyi bir ilk adım, dediğiniz gibi altta daha esnek matematik fonksiyonları oluşturup geri kalanını olduğu gibi bırakmaktır
      Sonra ekiple, arayüzü net bir facade sağlarken uygulamanın soyutlanmış kalmasını nasıl ileteceğinizi daha derinlemesine konuşabilirsiniz
  • Burada tarif edilen şey kötü soyutlama gibi geliyor
    Asıl sorun, insanların yalnızca iki üç örneğe bakarak tasarım yapması ve bunun gelecekteki kullanımları karşılayacak kadar genel olup olmadığını kontrol etmemesi

    • Özellikle iyi bir yaklaşım, ortak kısımları yalnızca çok basit fonksiyonlar olarak soyutlamaktır
      Soyutlamayı aşağıdan yukarıya yapmalısınız; yukarıdan aşağıya değil
      Her şeyin tek bir yerde gerçekleştiği ve 2^n kombinasyonu işleyen tek bir nokta yaratmaya gerek yok
      Yine de tekrarı azaltabilir, tek bir noktadan değiştirebilir ve gerektiğinde özel değişiklik yapma becerisini koruyabilirsiniz
    • Gerçek hayattaki sorun, kimsenin yazdığı anda kötü soyutlama kullandığını bilmemesidir. Bilselerdi kullanmazlardı
      Bu yüzden sadece “kötü soyutlamadan kaçının” ya da “gelecekteki kullanımları karşılasın” demek yeterli değil
      Genelde kimse geleceği öngöremez
      Soyutlama, doğru hissettirdiğinde bile son derece dikkatli kullanılmalı. Aşırı şüpheci olmak daha iyidir
    • “Temiz” sürümün sorunu, her şeyin tamamen birbirine bağlı olması
      Matematik kodunda bir şeye dokunursanız her şeyi etkiler
      Bir noktada, bir miktar yinelenen kod bırakmak; kod yapısındaki ipuçları veya yorumlarla benzerliği göstermek ve zaman içinde temel farkları yorumlarda vurgulamak daha kolay hale gelir
      Bu tür kodlara yönelik temiz kod yaklaşımı, değişen gereksinimleri iyi yönetemez
      Sonunda çağrıldığı yere göre farklı kod yolları içeren bir yardımcı fonksiyon yığınına dönüşmesi kolaydır
      Bazen bunu soyutlayabilirsiniz; bazılarının zaten fark etmiş olabileceği gibi, önceki cümle nesne yönelimli polimorfizmi anlatıyordu
      Ama kesin gereksinimleri önceden nasıl bilebilirsiniz ki? Bu kadar erken aşamada “temiz kod” denemek, ancak kötü soyutlama ya da aşırı tasarımla sonuçlanır
      Doğru yaklaşım hiçbir şey yapmamak, olası sorunu not etmek ve problem alanı hakkında daha fazlasını öğrenene kadar beklemektir
    • Değişiklikler üzerinden kalıp keşfetme yöntemini giderek daha çok sevmeye başladım. Yeni özelliklerde ve hata düzeltmelerinde kalıp aramak
      Orijinal örnekte olduğu gibi biraz yinelenen ama kolay anlaşılan kod için pek endişelenmem
      Ama aynı sorunu üç yerde düzeltmem ya da yeni özellik kodunu üç yere eklemem gerekiyorsa endişelenirim
      O noktada, değiştirmem veya eklemem gereken kodu bir şekilde ortak bir konuma taşıyıp taşıyamayacağımı düşünmeye başlarım
    • Doğru
      İnsanlar tasarım desenlerini ya da DRY’yi okuyup, öğrenme aşamasında oldukları için çoğunlukla yanlış uygular ve sonra suçu orijinal kaynaklara atarlar
  • Rob Pike bir keresinde Go’nun bu hale gelmesinin nedenlerinden biri olarak “küçük bir kopya, küçük bir bağımlılıktan iyidir” demişti
    Programlama yaptıkça bunun ne anlama geldiğini daha iyi anlıyorum
    Tekrarın kendisi sorun değil. Önemli olan, şu anda okuduğunuz ve belki de değiştireceğiniz birimi kavramak
    DRY çoğu zaman başka bir soyutlama eklemek anlamına gelir; eğer bu soyutlama yeterince ortogonal değilse, artık bir değil iki birimi düşünmeniz gerektiği için durumu daha da kötüleştirmiş olursunuz