Clean Code Notlarım
Clean Code: A Handbook of Agile Software Craftsmanship-Robert Martin kitabını okurken aldığım notlar
1_Anlamlı isimlendirmeler:
Amacınızı belli eden isimler kullanın.
Anlamı dışında kelimeler ile isimlendirmeyin.
Kendi başına anlamı olmayan kelimeleri(noise words) kullanmayın.
Telaffuz edebildiğiniz isimler koyun(programlama sosyal bir etkinliktir adını söyleyemezseniz tartışamazsınız).
Bir ismin uzunluğu o değişkenin kapsam’ına(scope) göre doğru orantılı büyüklükte olmaldır.
Bilgileri değişken ismine şifreleme(örneğin tipini).
Tek kelimeli isimlendirmeler kötüdür çünkü ne olduklarını hatırlayamazsınız.
Sınıf isimleri isim olmaldıır. Metod isimleri yüklem olmalıdır. Erişimciler(accessor) “get”, “set” veya “is” olmalıdır.
Şakalı isimlendirmeler onların ne olduklarını hatırlamadığınızda artık komik olmayacaktır, yapmayın.
Eş anlamlılardan kaçının, konsept başına kelimeleri seçin.
Teknik isimler kullanmaktan çekinmeyin kodunuzu yine programcılar okuyacaktır.
Bariz olan bilgileri eklemeyin. Örneğin Gas station deluxe şirketinin her sınıfına GSD etiketini eklersen, kodlar arasında bir sınıf aradığında sonuç olarak her sınıfı alırsın.
2_Fonksiyonlar:
Olabildiğince az satır olmalıdır. Bir veya iki satır başı(indent) olmalıdır.
Fonksiyonlar sadece bir şeyi ve o şeyi de iyi yapmalıdır.
Fonksiyon başına bir soyutlama yapılmalıdır.
Uzun ve açıklayıcı isimlendirmeler kısa ve şifreli isimlendirmelerden iyidir.
Fonksiyon parametreleri: sıfır tane (niladik), bir tane( monadik), iki tane (dyadik) olabilir.Üç tane (tiradic) ve fazlası olduğunda nesne tabanlı programlama ile bu parametre sayısının azaltılabilir olması beklenir. Üç ve daha fazlı parametreli fonksiyonları test etmek çok zorlaşır.
Genel monadik yapılar: Soru sormak, yönetmek, durum gerçekleştirmek için kullanılabilir. Parametreleri işlem(transaction) için çıktı vermeyin onun yerine döndürün(return).
Bayrak(flag) parametreler: Bir fonksiyona parametre olaran boolean yollamak berbat bir yöntemdir.
Genel dyadic yapılar: Parametreler tek bir değerin sıralı parçaları olabilir. Bir fonksiyon ikiden fazla parametreye ihtiyaç duyuyor gibi gözüküyorsa muhtemelen kendi türlerinden bir sınıfa eklenmeleri(wrap) gerekir.
Her zaman “go-to” kullanmaktan kaçın. Çünkü Dİjkstra’nın yapısal programlama kuralı(Dijkstra’s structured programming rule) der ki: “Bir fonksiyonun en fazla bir girişi ve bir çıkışı olmalıdır”.
Eğer fonksiyonlarınız yeterince küçükse return, break, continue ifadeleri sorun yaratmaz. Ancak asla go-to kullanmayın.
4_Yorum(comment):
Yorumlar kötü kodu açıklamak için var gibidirler.
Yorum yazacağınız zamanı temiz kod yazmaya ayırın.
Temiz kod kendi kendini açıklayabilen koddur.
Unutmayın ki yorumlarda hataya sebebiyet verebilir.
Lisans ve yasal durumları belirtmek için, tercih veya amacınızı açıklamak için yorumlar yazılabilir.
Günlük yorumlarına (bu eklemeyi şu saatte şu kişi yaptı vb.) artık ihtiyaç yoktur. Eskiden kullanılırdı artık “Git” olduğu için kullanılmamakta.
Asla kodu yorum içerisinde bırakmayın.
Asla yorumda çok fazla ve gereksiz bilgi vermeyin.
5_Biçimleme(Formatting): Kodlama biçimi ve okunabilirlik kodun sürdürülebilirliğini ve geliştirilebilirliğini etkiler.
Metodlar arası bir adet boşluk bırakmak okunabilirliği arttırır.
Birbirileri ile yakın ilişki içerisinde olan değişkenler aynı dosyada ve birbirine yakın bulunmalıdırlar. Yazılımcının vaktinin büyük kısmı varolan kodu okurken geçer ve bu dosyalar arası geçiş süresini azaltmaya yarar.
Değişkenler kullanımlarına olabildiğince yakın tanımlanmalıdırlar.
Özel(Private) dğeişkenler sınıfın en üstünde tanımlanmalıdır.
Eğer bir fonksiyon diğerini çağırıyorsa vertikal olarak yakın olmalıdır ve çağıran çağırdığının üzerinde olmalıdır.
Kodun genişliği maksimum 120 karakter olmalıdır.
İşteki çalışma tkaımı olarak projenin başında yazım kurallarına karar verilir ve ona uygun kod yazılır.
6_Nesneler ve veri yapıları:
Veri bilgisi gizle ise fonksiyon isimleri de ona uygun olarak gizli olmalıdır. Nesneler bilgilerini soyutlamaların arkasına gizlerler ve fonksiyonlarını açık tutarlar ki gizli verilere erişilebilinsin.
Prosedür kodları(procedural code/data structures) yeni fonksiyon eklemeyi kolay hale getirir.
Nesne tabanlı kodlar varolan fonksiyonları değiştirmeden yeni sınıf eklemeyi kolay hale getirir.
Geliştirmenin kuralı: C sınıfının f metodu sadece c sınıfını çağırmalı, f tarafından oluşturulmuş bir nesne f’e parametre olarak gönderilir ve c’nin bir örnek değişkeni tarafından tutulur.
Veri aktarım nesneleri( DTO[data transfer objects]):
Veri yapılarının öz biçimi, genel değişkenlere sahip ve işlevleri olmayan bir sınıftır. Bu bazen bir veri aktarım nesnesi (DTO) olarak adlandırılır.
DTO’lar, özellikle veri tabanları ile iletişim kurarken veya soketlerden gelen mesajları ayrıştırırken çok kullanışlı yapılardır.
7_Hata İdaresi(Exception Handling):
Kodun içerisinde idare edilmiş hatalar open-closed principle’a aykırı kaçınılması gereken aykırı olaylardır. Kod hata alınmayacak bir biçimde yazılmalıdır.
Özel durum örüntüleri(special case pattern): Bir sınıf oluşturun veya bir nesneyi sizin için özel bir durumu ele alacak şekilde yapılandırın. Müşterinin istisnai davranışlarla uğraşması gerekmez. Bu davranış, özel durum nesnelerinde kapsüllenmiştir(encapsulated).
Asla null yollama(pass) veya dönme(return). Onun yerine boş liste veya benzerlerini kullanabilirsiniz ama null değer hata verir ve kontrol edilmelidir.
8_Sınırlar(boundaries):
Bazen 3. Parti uygulamalar kullanırız. We onları anlamak için test ettiğimizde(öğrenme-testleri(learning tests)) zor zamanlar yaşarız.
Öğrenme testlerinde üçüncü parti uygulamalara API(uygulama programlama arayüzü)(application programming interface) deriz.
Sınırdaki kodlar net ayrımlara ve hataların tanımlı olduğu testlere ihtiyaç duyar.
9_Birim Testler(unit tests):
TDD’nin(test temelli geliştirmenin) üç kuralı:
1_Hata alan bir birim testi yazmadan ürün kodu yazmamalısın.
2_ Başarısız olmak için yeterli olan ve derlemenin başarısız olduğu bir birim testinden daha fazlasını yazmamalısın.
3_ O an hata alan testi geçmek için yeterli olacak kadar daha fazla ürün kodu yazabilirsin.
Kirli(kötü) testler testsizlikten iyidir.
Test kodunda yapabildiğin ama üretim kodunda yapamadığın bazı şeyler vardır bunlar cpu ve hafıza verimliliği hatalarıdır ama temizlik(cleanliness) değildir.
JUnit testi içindeki her test fonksiyonu sadece bir iddia beyanı (assert statement) olamalıdır.
Testler F.I.R.S.T kuralına uygun olmalıdır.
Fast(hızlı): Testler hızlı çalışmalıdır.
Independent(bağımsız): Testler birbirinden bağımsız olmalıdır.
Repeatable(tekrar edilebilir): Her ortamda tekrar edilebilir olmalıdır.
Self Validating(kendini doğrular): Testlerin boole, testin kaldığını veya geçtiğini söyleyen, sonuçları olmalıdır.
Timely(zamanında): Üretim kodundan hemen önce yazılmalıdır.
10_Sınıflar:
Sınıfları sadece testlerin ulaşabileceği biçimde korumak isteyebiliriz.
Sınıflar küçük olmalıdır. Bir sınıfın boyutu o sınıfın görevleri ile orantılı olmalıdır. Görevleri de isimi ile orantılı olmalıdır.
Sınıflar tek görevli ve değiştirilmesi için tek bir sebebi olan yapıda olmalıdır.
Kısa ve çok sınıf ve fonksiyon yazmak iyi midir kötü müdür?
Çok sınıf ve çok fonksiyon alet çantasının gözleri gibidir ve çok olmaları iyidir. Alet çantanızın çok gözlü ve her gözünün düzenli olmasını mı istersiniz yoksa , içindeki aletlerin karışık bir biçimde durduğu az gözlü olmasını mı istersiniz?
Sınıflar birbirileri ile olan uyumlarını kaybettiklerinde onları anlamlı parçalara ayırın.
11_Sistemler(systems):
Sistemler de temiz olmalıdır.
Alan mantığına da dikkat edilmelidir yoksa TDD tedarikçilerinin çevikliğini ve faydaları bu durumdan etkilenir.
Tüm ilişkilendirme düzeylerinde amaç net olmalıdır.
POJO’lar yazmayın ve diğer kusursuz endişeleri istilacı olmayan bir şekilde incelemek için görünüş benzeri anlamlar kullanmayın.
12_Ortaya Çıkış(emergence):
Bir tasarım eğer bu biçimde ise basittir:
1_Runs all tests
2_Contains no duplication
3_Express the intent of the programmer
4_Minimize the number of classes and methods
!Kurallar önemlilik sırasında verilmiştir.
13_Eşzamanlılık(concurrency):
Eşzamanlılık bazen performansı iyileştirir.
Basit problemler için bile doğru eşzamanlılık karmaşıktır.
Eşzamanlılık hataları genelde tekrar etmeme eğilimindedirler. Bu nedenle tek seferlik hata şeklinde görülüp görmezden gelinmektedirler.
Eşzamanlılığın kendi geliştirilme döngüsü(life cycle) ve zorlukları vardır.
Veri kapsüllemeyi ciddiye al, paylaşılabilecek herhangi bir veriye erişimi sınırla(veya daha kötü bir seçenek olarak veriyi kopayalayabilirsin).
Bir paylaşılan nesnede birden fazla metod kullanmaktan kaçın.
Senkronize olan kısımları küçük tut.
Eşzamanlılık olan kodu diğer kodlardan ayır.
14_Successive Refinement(ardışık iyileştirme):
-Devam edecek-
Referanslar:
Clean Code: A Handbook of Agile Software Craftsmanship-Robert Martin