Robert C. Martin'den Clean Code kitabı bizim yazılım sektöründe oldukça popüler. Yazılım geliştiricilere kodun sadece çalışmasının yetmeyeceğini, aynı zamanda anlaşılır, sürdürülebilir, test edilebilir, genişletilebilir vb. olması gerektiğini ve bunun hangi yöntemlerle yapılabileceğini örneklerle anlatan kitabı tüm meslektaşlarıma öneriyorum. Sunum haline getirdiğim kendimce çıkardığım notları şuradan indirebilirsiniz.
Ayrıca bunlar da ilginizi çekebilir:
Kodumdan Kötü Kokular Geldiğini Nasıl Anlarım? - 1
Sunum PDF dosyası indirilemiyorsa içerik aşağıdaki gibidir.
Clean Code Notları
Robert C. Martin
Temiz kodun özellikleri
Verimli
Okunabilir
Test edilebilir
Sürdürülebilir
Yalın
Verimli
Okunabilir
Test edilebilir
Sürdürülebilir
Yalın
Tekrar (dublication) içermeyen
Anlamlı isimlendirmeli
Anlamlı isimlendirmeli
Amaç:
Kodu bulduğumuzdan temiz bırakmamızı sağlayacak duyarlılığı kazanmak
Kodu bulduğumuzdan temiz bırakmamızı sağlayacak duyarlılığı kazanmak
İsimlendirme
İsimlendirme niyeti belli etmelidir.
Yanlış bilgilendirmemelidir.
Telaffuzu mümkün olmalıdır.
Aranabilmelidir.
Kodlamadan kaçınılmalıdır.
Aynı konsepten bahsederken aynı isim kullanılmalıdır.
Aynı isim farklı konseptler için kullanılmamalıdır.
Zeki olmaya çalışılmamalı, sade herkesin anlayacağı isim kullanılmalıdır.
İsimlendirme niyeti belli etmelidir.
Yanlış bilgilendirmemelidir.
Telaffuzu mümkün olmalıdır.
Aranabilmelidir.
Kodlamadan kaçınılmalıdır.
Aynı konsepten bahsederken aynı isim kullanılmalıdır.
Aynı isim farklı konseptler için kullanılmamalıdır.
Zeki olmaya çalışılmamalı, sade herkesin anlayacağı isim kullanılmalıdır.
İsimlendirme
İsimleri değiştirmekten korkmamalı. Gerekli yerlerde
refactor yapılmalıdır.
Helper, Manager vb. genel isimler sınıfın herşeyi içeren torbaya döndüğüne işaret ediyor olabilir.
Helper, Manager vb. genel isimler sınıfın herşeyi içeren torbaya döndüğüne işaret ediyor olabilir.
Fonksiyonlar
Küçük olmalıdır. İdealde en fazla 20 satır olmalıdır.
Nested yapılar 2 seviyeden fazla olmamalıdır. If, else, while gibi blokların içi metoda alınarak tek satıra düşürülebilir.
Metod tek bir iş yapmalıdır. Tek sorumluluğu olmalıdır. (Single Responsibility Principle)
Küçük olmalıdır. İdealde en fazla 20 satır olmalıdır.
Nested yapılar 2 seviyeden fazla olmamalıdır. If, else, while gibi blokların içi metoda alınarak tek satıra düşürülebilir.
Metod tek bir iş yapmalıdır. Tek sorumluluğu olmalıdır. (Single Responsibility Principle)
Fonksiyonlar
Switch blokları doğası gereği n tane iş yaparlar. Mümkün olduğunca kaçınmalıdır.
Polimorfizm kullanarak switch blokları refactor edilebilir. (Abstract factory vb.)
Fonksiyonun ismi açıklayıcı olmalıdır.
Yaptığı iş anlaşılmalıdır.
Switch blokları doğası gereği n tane iş yaparlar. Mümkün olduğunca kaçınmalıdır.
Polimorfizm kullanarak switch blokları refactor edilebilir. (Abstract factory vb.)
Fonksiyonun ismi açıklayıcı olmalıdır.
Yaptığı iş anlaşılmalıdır.
Fonksiyonlar
Fonksiyonların argüman sayısı en aza indirgenmelidir. Mümkünse sıfır, en kötü üç argüman almalıdır.
Argüman sayısı artıyorsa, argüman objesi oluşturmalı, argümanlar bu sınıf ile geçirilmelidir.
Output argümanlar ekstra dikkat gerektireceğinden mümkün olduğunca kaçınılmalıdır.
Fonksiyonların argüman sayısı en aza indirgenmelidir. Mümkünse sıfır, en kötü üç argüman almalıdır.
Argüman sayısı artıyorsa, argüman objesi oluşturmalı, argümanlar bu sınıf ile geçirilmelidir.
Output argümanlar ekstra dikkat gerektireceğinden mümkün olduğunca kaçınılmalıdır.
Fonksiyonlar
Boolean flag argüman alan fonksiyon büyük olasılıkla birden fazla iş yapıyordur. Fonksiyon ayrılarak flag argümanından kurtulunmalıdır.
Fonksiyonun yan etkisi olmamalıdır. Var ise, fonksiyon isminde belirtilmelidir. (Unutmayın, fonksiyon bir iş yapmalıydı)
Boolean flag argüman alan fonksiyon büyük olasılıkla birden fazla iş yapıyordur. Fonksiyon ayrılarak flag argümanından kurtulunmalıdır.
Fonksiyonun yan etkisi olmamalıdır. Var ise, fonksiyon isminde belirtilmelidir. (Unutmayın, fonksiyon bir iş yapmalıydı)
Fonksiyonlar
Bir fonksiyon ya nesnenin durumunu değiştirmeli ya da nesneyle alakalı bilgi dönmelidir. İkisini aynı anda yapmamalıdır.
Örneğin;
public boolean set(String attribute, String value); if (set("username", “unclebob"))...
Set metodu birden fazla iş yapıyor...
Bir fonksiyon ya nesnenin durumunu değiştirmeli ya da nesneyle alakalı bilgi dönmelidir. İkisini aynı anda yapmamalıdır.
Örneğin;
public boolean set(String attribute, String value); if (set("username", “unclebob"))...
Set metodu birden fazla iş yapıyor...
Fonksiyonlar
Fonksiyondan hata kodu dönmektense exception
fırlatmak tercih edilmelidir.
Try/Catch blokları fonksiyonlara dönüştürülmeli, blok sadeleştirilmelidir.
Try/Catch blokları fonksiyonlara dönüştürülmeli, blok sadeleştirilmelidir.
Fonksiyonlar
Single-entry, single-exit kuralı uzun fonksiyonlar için
mantıklıydı. Metodlarımızı kısa tutacağımız için birden
fazla return, break kullanılabilir, hatta daha açıklayıcı bile
olabilir.
Yorumlar
Kötü koda açıklama yazmakla uğraşılmamalı, kodu
tekrar yazmalıdır.
Kod açıklamaya gerek kalmayacak kadar okunur ve anlaşılır olmalıdır.
Derdimizi kodla anlatmalıyız.
Kod açıklamaya gerek kalmayacak kadar okunur ve anlaşılır olmalıdır.
Derdimizi kodla anlatmalıyız.
Yorumlar
Yorumun gerekli olduğu yerler de vardır.
Yasal zorunluluklar. Lisans bilgilerini içeren yorumlar.
Koddaki bir tasarımsal kararın arkasındaki neden yorum olarak eklenebilir.
Yasal zorunluluklar. Lisans bilgilerini içeren yorumlar.
Koddaki bir tasarımsal kararın arkasındaki neden yorum olarak eklenebilir.
Yorumlar
Geliştiriciyi çalıştırılacak kodun sonuçlarına karşı
uyarmak gerektiğinde yorum kullanılabilir.
TODO yorumları unutulmamak şartıyla faydalıdır. Javadoc yorumları dökümantasyon için faydalıdır.
TODO yorumları unutulmamak şartıyla faydalıdır. Javadoc yorumları dökümantasyon için faydalıdır.
Yorumlar
Kodu okuyarak anlayabileceğimiz şeyler için yorum yazılmamalıdır. Gereksiz kalabalık yaparlar.
Yanlış bilgi içeren, yanlış yönlendiren yorumlar tehlikelidir. Bir an önce kurtulunmalıdır.
Yoruma alınmış kod bırakılmamalıdır, silinmelidir. Siz silmezseniz, birinin işine yarayacak düşüncesiyle kimse silmeye cesaret edemez.
Kodu okuyarak anlayabileceğimiz şeyler için yorum yazılmamalıdır. Gereksiz kalabalık yaparlar.
Yanlış bilgi içeren, yanlış yönlendiren yorumlar tehlikelidir. Bir an önce kurtulunmalıdır.
Yoruma alınmış kod bırakılmamalıdır, silinmelidir. Siz silmezseniz, birinin işine yarayacak düşüncesiyle kimse silmeye cesaret edemez.
Formatlama
Kodun çalışır olması kadar okunabilir olması da
önemlidir.
Kod listesi okurken gazete okuyor hissi vermeli, yukarıdan aşağıya genelden özele doğru bir yapı oluşturulmalıdır.
Kod listesi okurken gazete okuyor hissi vermeli, yukarıdan aşağıya genelden özele doğru bir yapı oluşturulmalıdır.
Formatlama
Alakalı metodlar birbirine yakın yerleştirilmelidir.
Değişkenler kullanıldığı yere mümkün olan en yakın yerde tanımlanmalıdır.
Yatay satır uzunluğu, sayfada sağa doğru scrola gerek bırakmamalıdır.
Alakalı metodlar birbirine yakın yerleştirilmelidir.
Değişkenler kullanıldığı yere mümkün olan en yakın yerde tanımlanmalıdır.
Yatay satır uzunluğu, sayfada sağa doğru scrola gerek bırakmamalıdır.
Formatlama
Takımca formatlamanın nasıl olacağına karar vermeli ve
tüm geliştiriciler bu kurallara uymalıdır.
Hataları Yönetme
Hata kodu dönmektense Exception kullanılmalıdır.
Böylece çağıran kod hata kodu kontrol etmekten
kurtulur ve esas işi yapan kod, hata handling kodundan
ayrıldığı için daha temiz olur.
Hataları Yönetme
Unchecked exception tercih edilmelidir. Checked exception fırlatan bir metodun catch’i 3 seviye yukardaysa, exceptiondaki bir değişiklik tüm seviyelerin değişmesine ve yeniden compile-deploy edilmesine sebep olmaktadır.
Checked exception olmadan da sağlam yazılım yapılabilir. Örneğin; C#, C++, Python ve Ruby dillerinde Checked exception yoktur.
Unchecked exception tercih edilmelidir. Checked exception fırlatan bir metodun catch’i 3 seviye yukardaysa, exceptiondaki bir değişiklik tüm seviyelerin değişmesine ve yeniden compile-deploy edilmesine sebep olmaktadır.
Checked exception olmadan da sağlam yazılım yapılabilir. Örneğin; C#, C++, Python ve Ruby dillerinde Checked exception yoktur.
Hataları Yönetme
Exception içine hata ile alakalı içeriksel bilgiler de
konulmalıdır. Ne yapmaya çalışırken hata oluştuğu
bilgisi debug yaparken yardımcı olacaktır.
Hataları Yönetme
Duruma özel nesne ile çözülebilecek exceptional
case’ler, try/catch ile değil, bu nesne ile çözülmelidir.
(SPECIAL CASE PATTERN [FOWLER]
Hataları Yönetme
try {
MealExpenses expenses = expenseReportDAO.getMeals(employee.getID());
try {
MealExpenses expenses = expenseReportDAO.getMeals(employee.getID());
m_total += expenses.getTotal();
} catch(MealExpensesNotFound e) {
m_total += getMealPerDiem();
}
// yerine
MealExpenses expenses = expenseReportDAO.getMeals(employee.getID());
m_total += expenses.getTotal();
// Special Case obejesi
public class PerDiemMealExpenses implements MealExpenses {
public int getTotal() {
// return the per diem default }
}
Hataları Yönetme
Metodlardan null dönmek hatalara davetiye çıkarır. Null dönmemeli, Exception fırlatmalı veya SPECIAL CASE nesnesi kullanılmalıdır.
Metodlara null parametre geçirmek, null dönmekten daha kötüdür. Null parametre geçirmekten sakınmalıdır.
Metodlardan null dönmek hatalara davetiye çıkarır. Null dönmemeli, Exception fırlatmalı veya SPECIAL CASE nesnesi kullanılmalıdır.
Metodlara null parametre geçirmek, null dönmekten daha kötüdür. Null parametre geçirmekten sakınmalıdır.
Birim Testleri
TDD (Test Driven Development) pratiğinin üç temel yasası vardır.
1- Fail eden bir test yazmadan production kodu yazma
2- Fail etmeye yetecek kadardan fazla test yazmaya devam etme.
3- Fail eden testi geçecek kadardan fazla production kod yazma. Testi geçecek kadar geliştirmen yeterli.
TDD (Test Driven Development) pratiğinin üç temel yasası vardır.
1- Fail eden bir test yazmadan production kodu yazma
2- Fail etmeye yetecek kadardan fazla test yazmaya devam etme.
3- Fail eden testi geçecek kadardan fazla production kod yazma. Testi geçecek kadar geliştirmen yeterli.
Birim Testleri
Bu sayede fail edecek test yaz - kodu geliştir - fail edecek test yaz şeklinde bir döngüye girilir.
Böylece production kodu testlerle beraber üretilir.
Bu sayede fail edecek test yaz - kodu geliştir - fail edecek test yaz şeklinde bir döngüye girilir.
Böylece production kodu testlerle beraber üretilir.
Birim Testleri
Test sınıfları da production kod kalitesinde temiz tutulmalıdır. İkinci sınıf vatandaş muamelesi görmemelidir.
Testler temiz tutulmadığında sürdürülemez ve bir süre sonra production kod testsiz kalma tehlikesiyle karşı karşıya kalır.
Testsiz kalan production kodda değişiklik yapmaya cesaret etmek zordur. Nerenin bozulduğu anlaşılamaz
Test sınıfları da production kod kalitesinde temiz tutulmalıdır. İkinci sınıf vatandaş muamelesi görmemelidir.
Testler temiz tutulmadığında sürdürülemez ve bir süre sonra production kod testsiz kalma tehlikesiyle karşı karşıya kalır.
Testsiz kalan production kodda değişiklik yapmaya cesaret etmek zordur. Nerenin bozulduğu anlaşılamaz
Birim Testleri
Test metodlarındaki assert sayısı en aza indirgenmelidir. Testler çalıştırıldığında fail eden bir assert yüzünde onun altında kalan assertlerin sonuçları muamma olmaktadır.
One assert per method en idealidir.
Test metodu sadece bir konuyu test etmelidir.
Birden fazla durum için farklı test metodları yazılmalıdır.
Test metodlarındaki assert sayısı en aza indirgenmelidir. Testler çalıştırıldığında fail eden bir assert yüzünde onun altında kalan assertlerin sonuçları muamma olmaktadır.
One assert per method en idealidir.
Test metodu sadece bir konuyu test etmelidir.
Birden fazla durum için farklı test metodları yazılmalıdır.
F.I.R.S.T. kuralı
Testler F.I.R.S.T. kuralına uymalıdır:
Fast: Testler hızlı çalışmalıdır. Yavaş çalışan testi kimse çalıştırmak istemez, hatalar tespit edilemez.
Independent: Testler birbirinden bağımsız çalışabilmelidir.
Testler F.I.R.S.T. kuralına uymalıdır:
Fast: Testler hızlı çalışmalıdır. Yavaş çalışan testi kimse çalıştırmak istemez, hatalar tespit edilemez.
Independent: Testler birbirinden bağımsız çalışabilmelidir.
F.I.R.S.T. kuralı
Repeatable: Testler her ortamda tekrarlanabilmelidir.
Self-validating: Test sonucunu anlamak için fazla düşünmeye gerek olmamalıdır. Test ya geçmeli ya fail etmelidir. Durumu anlamak için çıktıları incelemek vs. gerekmemelidir.
Timely: Testler zamanında yazılmalıdır. Production kodla beraber geliştirilmelidir.
Repeatable: Testler her ortamda tekrarlanabilmelidir.
Self-validating: Test sonucunu anlamak için fazla düşünmeye gerek olmamalıdır. Test ya geçmeli ya fail etmelidir. Durumu anlamak için çıktıları incelemek vs. gerekmemelidir.
Timely: Testler zamanında yazılmalıdır. Production kodla beraber geliştirilmelidir.
Sınıflar
Yukarıdan aşağıya statik değişkenler (önce publicler sonra private statikler), sonra instance değişkenleri (public, private sırasında) daha sonra public metodlar ve private metodlar gelmelidir.
Sınıfı okurken gazete okuyor hissi vermelidir.
Yukarıdan aşağıya statik değişkenler (önce publicler sonra private statikler), sonra instance değişkenleri (public, private sırasında) daha sonra public metodlar ve private metodlar gelmelidir.
Sınıfı okurken gazete okuyor hissi vermelidir.
Sınıflar
Sınıflar olabildiğince küçük olmalıdır. Sorumluluklar olabildiğince küçük parçalara bölünmelidir.
Sınıfa isim vermekte zorlanıyorsanız, sınıfın olması gerektiğinden büyük olduğu anlaşılabilir.
Single Responsibility Principle der ki, bir sınıfın değişmesi için sadece bir neden olmalıdır.
Sınıflar olabildiğince küçük olmalıdır. Sorumluluklar olabildiğince küçük parçalara bölünmelidir.
Sınıfa isim vermekte zorlanıyorsanız, sınıfın olması gerektiğinden büyük olduğu anlaşılabilir.
Single Responsibility Principle der ki, bir sınıfın değişmesi için sadece bir neden olmalıdır.
Sınıflar
Sınıfın sorumluluğu arttıkça, değişime uğrama olasılığı o
kadar artmaktadır.
Sınıfın manipüle ettiği değişken sayısına bakarak bu değişkenlerden yeni sınıflar üretilebilir mi diye sorgulamalıdır.
Sınıfın manipüle ettiği değişken sayısına bakarak bu değişkenlerden yeni sınıflar üretilebilir mi diye sorgulamalıdır.
1 Yorumlar
Genel olarak güzel bir özet olmuş. Paylaşım için teşekkürler.
YanıtlaSilF.I.R.S.T. kuralı ikinci başlık, Self-validating maddesinde yazım hatası var sanırım: "Test sonucunu anlamak için fazla düşünmeye gerek olmalıdır." ifadesi yerine "Test sonucunu anlamak için fazla düşünmeye gerek olmamalıdır." şeklinde.