in Temiz Kod

Fonksiyonlar

Nesneye yönelimli programlama kullanan herkes hiç şüphesiz fonksiyonları kullanmaktadır. Bu da temiz kod yazmamız gerektiğinde bu yapıya büyük önem verir. Bu kurallara göz atalım.

Küçük!

İlk kuralımız fonksiyonların uzunluğu küçük olmalıdır.İkinci kural ise ondan daha da küçük olmalıdır. Peki ne demek bu? 500 satırlık fonksiyon yazıp ne yazdım be deme demek :) Özellikle Github sayesinde devamlı proje inceleyen birisi olarak en çok karşılaşılan hatanın bu olduğunu görüyorum. Bunu bende yaptım tabi ki. Ancak fonksiyonları uzun tutmak hem Tek Sorumluluk Prensibine aykırı olacaktır hem de ileride o kodun bakımını zorlaştıracaktır. Bu nedenle fonksiyonumuz çok büyükse mümkün oldukça küçük fonksiyonlara ayırmalıyız.

Peki, ne kadar küçük olmalı? Cevap: Olabildiğince.

Tek , iki veya üç satır. Mümkün oldukça küçük tutmaya çalışacağız. Fonksiyonlara isim verirken tek bir işe yönelik verdiğimizde zaten o fonksiyonun çok fazla iş yapamayacağını bir başka deyişle yapmaması gerektiğini anlayacaksınız.

Bloklar ve Derinlik

Bu kurala göre if,else,while gibi komutların içindeki iş yapan kodlar tek satır uzunluğunda olmalı. Muhtemelen o tek satırda bir fonksiyon çağrımı olacaktır. Böylelikle kodu okurken neyin ne yaptığını sadece isimlerden düz bir şekilde anlayacağız.

Bir diğer kural ise derinlik. Bir if komutu kullandığımızda bir alt satırda içe boşluk atarız.Eğer hemen devamında ikinci bir if gelirse iç içe (nested) bir yapı ortaya çıkar. Dolayısıyla derinlik git gide artar. Bu nedenle derinliği eğer mümkünse birden yoksa ikiden yukarıda tutmamalıyız. Böylelikle kodun okunabilirliği çok daha kolay olacaktır.

Tek Bir İş

Gayet basit.Adından da belli olacağı gibi bir fonksiyon tek bir iş yapmalı.Hayır hayır iki üç iş değil bildiğin tek iş. Eğer fonksiyonun getRandomNameForTempFolder() adındaysa buradan sana sadece rastgele bir isim geleceğini anlayabilirsin. Bu isminde geçici bir dosya için kullanılacağını anlayabiliyorsun.Ama bu fonksiyonun içinde bir de gidip dosya okuma işlemi yaparsak ne olur? Tek iş yapmamış olur. Robert Martin’in dediği gibi;

FUNCTIONS SHOULD DO ONE THING . THEY SHOULD DO IT WELL .
THEY SHOULD DO IT ONLY .

Mealen;

Fonksiyonlar tek birşey yapmalı.Onu iyi yapmalılar ve sadece onu yapmalılar.

Step Down Rule

Bir fonksiyon içinde çağrılan fonksiyonlar o fonksiyonun hemen altında çağrılma sırası ile yer edinmesi gerekir. Bunu örnekle görmek daha iyi olacaktır.

Bu sınıf kendi projemden bir bölüm. Görüldüğü üzere ilk metodumuz getLanguageInstance(). Onun içinde prepareInstance() metodu çağrılıyor.Bu nedenle getLanguageInstance() metodunun hemen altında prepareInstance() metodu yer almalı. Aynı şekilde prepareInstance()  metoduna bakalım. İlk isCompilerMapNull() metodu çağrılmış. Ardından addExistLanguages() çağrılıyor. Dolayısıyla çağrılma sırasına göre ilgili metodun altında sıralanıyor. İşte buna Step Down Kuralı deniyor. Böylelikle çağrılan metodu kolayca bulabiliyoruz. Böyle bir şart tabi ki yok. Ancak bir düzen olması açısından kullanılmalı.

Açıklayıcı İsimlendirme

İsimlendirme kısmında buna detaylıca değindik.Yine de hatırlamakta fayda var. Fonksiyonun ne iş yaptığını anlamamız için ona açıklayıcı bir isim vermeliyiz. Aksi takdirde anlaşılır olmaz.

Değişken Sıralaması

Sınıfın en üstünde sıralama aşağıdaki şekilde olmalıdır.

Fonksiyon Parametreleri

En iyi parametre sayısı sıfırdır. Ancak en fazla 3 parametre kabuldür. 4. Parametre kabul edilemez. Bu nedenle mümkün oldukça parametre sayısını küçük tutmalıyız. Eğer parametre sayısını küçültemiyorsak o parametreleri bir nesne veya veri yapısı aracılığıyla geçirebiliriz.Bir örnek ile inceleme yapalım.

convertStringArrayToIntArray(int[] al,String[] az)

Böyle bir fonksiyon tanımlamasında üç sorun bulunuyor.

  • Parametre isimleri anlamsız. String source gibi bir tanımlama daha iyi olabilirdi.
  • Metot ismine göre string’ten int’e bir dönüşüm anlaşılıyor. Bu nedenle parametre sırası tersi olsa daha güzel olabilir.
  • Metot isminde bir iş yapılması olduğu için ve bir output geleceği sezilebiliyor.Hem de parametre azaltma kuralımız için sadece int array’ı return etmek daha mantıklı.

 

Flag-Null Argüman

Boolean argüman her zaman o metodun tek sorumluluk prensibine aykırı hareket etmesine yol açar. Çünkü iki farklı durum için iki farklı iş ortaya çıkacaktır. Aynı durum null içinde gerçekleşir.Bir parametre ya null’dur ya da değildir.

Output Argüman

populateWithEvenNumbers(count,list)

Burada List yollanıp o List üzerinde işlem yapılıp geri döndürüldüğünü düşünelim. Bu durumda List argümanımız output argümanı olacaktır. Böyle bir kullanım argüman sayısını gereksiz yere arttırıyor. Onun yerine List’i içeride tanımlayıp return etmek daha mantıklı olacaktır.

Yorum yaz

Comment