Bad Smells In Code | Refactoring

Refactoring, kodun dış davranışını değiştirmeyecek şekilde iç yapısının iyileştirilme işlemidir. Amacı, kodun anlaşılabilirliğini ve değiştirilebilirliğini arttırmaktır. Üzerinde çalıştığımız kod, refactoring ihtiyacı hissetmemiz için bazı kötü kokular barındırabilir.😒 Bu kokular genellikle programın çalışmasını engellemezler ancak projedeki gelişimi yavaşlatabilen, ileride hata ya da başarısızlık riskini arttırabilecek zayıflıkları belirtirler. Bu zayıflıkların bilincinde olarak kod yazma, review süreçlerine dahil olma ve şuan çalıştığım projede refactor yapabilmek için aldığım notları bu yazıda paylaşıyor olacağım. ✌️

Long method: Bir metodun içeriği uzadıkça anlaşılması da bir o kadar zorlaşır. (İçeriği on satırdan daha uzun metodlar refactor için soru işareti uyandırmalı.)

Large class: Bir class’ın çok sayıda field /fonksiyon / kod satırı içermesi durumunda o class’ın ilgili modüllerinin ayıklanmalı (Extract class).

Primitive obsession: Basit işler için küçük nesneler yerine primitive(ilkel) type kullanılması (para birimi, diziler, telefon numarası için özel stringler, vb.).

Long parameter list: Bir metodun üç veya dörtten fazla parametre alması anlaşılırlığı zorlaştırır ve bug oranını yükseltir.

Data clumps: Bazen kodun farklı bölümleri aynı değişken gruplarını içerir(örneğin veritabanı bağlantısı için gerekli parametreler). Bu veri kümeleri kendilerine ait sınıflara dönüştürülmelidir.

Alternative classes with different interfaces: İki sınıfın aynı işlevleri yerine getiren farklı isimlere sahip metodlar içermesi durumu (Sınıflardan birini oluşturan programcı muhtemelen işlevsel olarak eşdeğer bir sınıfın zaten var olduğunu bilmiyordur.).

Refused bequest: Bir üst sınıftan miras alan bir alt sınıfınız olduğunu düşünelim. Ancak alt sınıfın, üst sınıf tarafından sağlanan tüm davranışlara ihtiyacı olmasın. Bu durumda, alt sınıf, üst sınıfın bazı davranışların/isteklerini reddeder.

Switch statements: Karmaşık switch/if statement’ları yeni bir koşul eklendiğinde, koddaki tüm switch operatörlerini bulup değiştirmeyi gerektirecektir.(Genel bir kural olarak kodda bu ifadeleri gördüğümüzde polymorphism’i düşünmemiz gerekir.).

Temporary field: Geçici alanlar değerlerini yalnızca belirli koşullar altında alır ve bu koşulun dışında değerleri boştur.

Divergent change: Bir modülde değişiklik yaparken modülden ilgisiz farklı yerlerde değişiklik yapılması durumu. Örneğin; yeni bir ürün tipi ekleneceği zaman arama,listeleme metodlarında da değişiklik yapılması.

Parallel inheritance hierarchies: Hiyerarşi büyüdükçe karmaşıklık artar. Bu durumda hiyerarşideki bir class için bir sub class oluşturmak istediğimizde, farklı bir class için de sub class oluşturmak zorunda kaldığımızı farkederiz.

Shotgun surgery: Kodda bir değişiklik yapıldığında, birçok farklı sınıfta birçok küçük düzenlemeye ihtiyaç duyulduğu durumdur.

Comments: Metodların yorum satırlarıyla dolu olması durumu. (Koda çok yorum satırı yazılması demek kodun anlaşılır olmadığından kaynaklanıyor olabilir/kötü bi kokuyu gizlemek için deodorant sıkılması gibi)

“The best comment is a good name for a method or class.”

Duplicated code: Copy+paste programlamadan kaynaklanan aynı kod yapısının birden fazla yerde tekrar edilmesi durumu.

Dumb data class: Bir classın, yalnızca fieldlar ve bu fieldlara erişmek için metodlar içermesi (getter ve setter). Bu sınıflar herhangi bir ek işlevsellik içermez ve sahip oldukları veriler üzerinde bağımsız olarak çalışamazlar.

Dead code: Uzun süredir kullanılmayan değişken,parametre,field,metod veya class(genellikle eski olduğu için) dead code olarak adlandırılır ve temizlenmesi gerekir.

Feature envy: Bir metod, başka bir nesnenin verilerine kendi verilerinden daha fazla erişiyorsa gözden geçirilmelidir.

Inappropriate intimacy: Bir sınıfın, başka bir sınıfın iç fieldlarını ve metodlarını kullanması bağımlılığı arttırır.

Message chains: Kodda şuna benzer bir call dizisi görürsünüz:

Bu zincirler, client’ın class yapısı boyunca gezinmeye bağlı olduğu anlamına gelir. Yapılaca herhangi bir değişiklikte client’ın da değiştirilmesi gerekliliği ortaya çıkar.

Middle man: Bir nesne işlevselliklerini yerine getirmek için başka nesnelere(middle man) bağımlıysa, bu bağımlılık ortadan kaldırılmalıdır(remove middle man) fakat middle man sınıfları, Facade design pattern’ında olduğu gibi durumlarda yardımcı olabilirler.

Bir sınıfın diğer nesnelere delege olan çok fazla metodu vardır.
Bu metodları silerek client’ın doğrudan son metodu çağırmasını sağlayabiliriz.

Buraya kadar clean code’da olmaması gereken durumları başlıklar altında toplayarak örneklendirmeye ve özetlemeye çalıştım. Bu durumların giderilmesi için birçok refactoring teknikleri mevcut. Aşağıda paylaştığım kaynaktan tekniklere ve kod örneklerine ulaşabilirsiniz.👇

Vakit ayırdığınız için teşekkür ederim.💛