Merhaba ,
Eğer okumadıysanız bu serinin ilk yazısı olan Clean Code [ Temiz Kodlama ] Prensipleri – Giriş ile başlamanızı tavsiye ederim.
Önceki yazımızda Temiz Kodlama prensipleri üzerinde genel hatlarıyla tecrübeler edinmiştik , şimdi biraz daha spesifik bir konu özelinde değerlendirme yapacağız. “METHODS – FUNCTIONS”
Rule Of 7
İnsanlar kısa süreli bellekte sadece 7 maddeyi tutabilirler.Temiz kod yazarken bu kuralı unutmayalım.
Değişkenler
Methodlarda değişken tanımlamalarımızı Just-in-time yani ilk değer atamasından hemen önce yapılmalı.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//yanlış int minUserNameLenght = 6; int maxUserNameLenght = 20; bool isAlphaNumeric; if(userName.Length < minUserNameLength) return false; if(userName.Length > maxUserNameLength) return false; isAlphaNumeric = userName.All(Char.IsLetterOrDigit); ------------------------------------------------------------ // doğru int minUserNameLenght = 6; if(userName.Length < minUserNameLength) return false; int maxUserNameLenght = 20; if(userName.Length > maxUserNameLength) return false; bool isAlphaNumeric = userName.All(Char.IsLetterOrDigit); |
Parametreler
Methodlarımızın parametre sayılarından bir şeylerin doğru veya yanlış gittiğini anlayabiliriz. Fazla parametre alan methodlarımız parçalanmalı veya parametre olarak Model almalıdır.
Aşağıdaki örnekte kullanıcı kaydetme işlemi içinde sendEmail , sendBill gibi parametrelerin olması aslında bu method’un doğru kurgulanmadığına işaret. Method hem kullanıcı kaydedip hem de mail gönderme işlemini yapıyorsa Single Reponsible değildir. Birden fazla sorumluluğu olan methodlar parçalanmalıdır.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void SaveUser(string userName, string password, string email, bool sendEmail, bool sendBill, bool printReport) { } |
Methodlara kısa bir gitiş yaptıktan sonra İlk önce bir method oluşturmakdaki amaçlarımızı sıralayalım. Aslında bu yazdıklarımız Temiz Kod yazımındaki prensiplerimiz yerine de geçebilir. Bu maddeler ile method refactor için doğru bakış açısını yakalayabiliriz.
- Tekrarlamayı azaltmak
- Kendini tekrar etme (DRY – Don’t Repeat Yourself ) prensibini düşünürsek , methodlar birbirini tekrar eden kod parçacıklarını tekilleştirmek için kullanılır.
- Karmaşıklık ve Girintiler azaltmak
- Kod bloğu ilk bakışta size karmaşık geliyorsa ve iç içe bir den fazla if blogu varsa. Tam beklediğimiz method refactor blokları.
12345678910111213if(){if(){if(){}}}
- Kod bloğu ilk bakışta size karmaşık geliyorsa ve iç içe bir den fazla if blogu varsa. Tam beklediğimiz method refactor blokları.
- Belirsiz niyetlerden kurtul
- Bazı kod bloklarında yazılımcı için en önemli ipucu method isimleri olur. Niyetin belli olmadığı yerlerde kod method üzerinden işlenebilir.
- 1 den fazla işlem varsa bölümlendir
- Tek sorumluluk ( Single Responsibility ) prensibiyle method tek işlem özelinde değerlendirilmelidir. Bu nedenle birden fazla işlemin olduğu methodlar ve kod bloklarını düzeltilmelidir.
Method oluşturmak için elimizde 4 farklı madde var, bu maddelerden elde ettiğimiz çıkarımları Temiz kodlama ile birleştirmeye çalışalım. Detaylandırdığımız maddeleri aşağıda inceleyebilirsiniz.
Tekrarlamayı azaltmak
Bu maddede DRY prensibinden bahsetmiştik. Kod tekrarlamanın yanına kod kopyalamayı da eklemek istiyorum. Copy – Paste sizi tembelliğe itecektir. Bir problemi birden fazla çözüm yolu vardır. Copy – Paste ile kod tekrarlamak farklı düşünme alternatiflerinizi çöpe atmak demektir.
Genel anlamda kod tekrarlarınızın projemide etkisi ;
- Okunabilirliği azaltır
- Kodunuzu daha kompleks hale getirir
- Hata yapma olasılığınızı arttırır ve bugFix maliyetiniz artar.
- Bakım (maintance) maliyetiniz artar
Karmaşıklık ve Girintiler
Yukarıda başlığımızı kısaca açıklamıştık. Şimdi de karmaşıklık ve girinlilere neden olabilecek kod bloklarını Clean-Code prensibiyle çözümleyeceğiz. Ana hedefimiz girintiyi azaltmak
-
Exctract Method
Bu yöntemde önceliğimiz kod bloğunu anlaşılabilir hale getirene kadar methodlara bölmek.
12345678910111213141516if(){if(){do{//// kodlar//} while()}}12345678910111213141516171819202122if(){if(){DoSomething();}}private void DoSomething(){do{//// kodlar//} while()} -
Fail Fast
Kodumuzda hata fırlatıcaksak bunu ana kod bloğundan önce yapmalıyız. Önce hataları handle et daha sonra iş yapacak kodu yaz.
123456789101112131415161718192021222324public void Login(string userName, string password){if(!string.IsNullOrWhiteSpace(userName)){// kodif(!string.IsNullOrWhiteSpace(password)){// Login}else{throw ...}}else{throw ...}}12345678910111213public void Login(string userName, string password){if(string.IsNullOrWhiteSpace(userName))throw ...;if(string.IsNullOrWhiteSpace(password))throw ...;// Login;}Yukarıdaki kodlarda Fail Fast yöntemiyle girintileri minimuma indirdik, okunabilirliği arttırmış olduk.
-
Return Early
Fail Fast mantığıyla aynı düşünebiliriz. Fail Fast kazanımlarının hepsi geçerlidir. Methodun işleyişine göre return edilebilecek değerlerin öncelikli olarak geri dönülmesi ile uygulanır.
1234567891011121314151617181920212223242526private bool ValidUserName(string userName){int minUserNameLenght = 6;int maxUserNameLenght = 20;bool isValid = false;if(userName.Length >= minUserNameLength){if(userName.Length <= maxUserNameLength){bool isAlphaNumeric = userName.All(Char.IsLetterOrDigit);if(isAlphaNumeric){if(!ContainsCurseWords(userName)){isValid = IsUniqueUserName(userName);}}}}return isValid;}123456789101112131415161718192021private bool ValidUserName(string userName){int minUserNameLenght = 6;if(userName.Length < minUserNameLength)return false;int maxUserNameLenght = 20;if(userName.Length > maxUserNameLength)return false;bool isAlphaNumeric = userName.All(Char.IsLetterOrDigit);if(!isAlphaNumeric)return false;if(ContainsCurseWords(userName))return false;return IsUniqueUserName(userName);}