Java Kodunuzun Nesne-Merkezli Olmadığının 10 İşareti – X: Aşırı miktarda karar ifadelerine sahip metotlar.

Geliştirdiğimiz Java kodunun nesne-merkezli olmadığının 10 işaretinin neler olduğunu bu yazıda listelemiş ve ilk sekiz maddeyi daha önce ele almıştık. Şimdi de dokuzuncu maddeyi inceleyelim:

Aşırı miktarda karar ifadelerine sahip metotlar. (Methods that include excessive number of decision statements.)

Bu çalışma çerçevesinde daha önce bu yazıda metotların karmaşıklığından bahsetmiş ve metot karmaşıklığıyla ilgili, metot uzunluğu, geçilen parametre sayısı ve metota verilen kararların sayısını, metot karmaşıklığını belirleyen en temel üç etmen olarak ele almıştık. Bu yazıda bu etmenlerden üçüncüsünün detaylarını ele alacağız.

Yazılımlar, gerek iş süreçlerinde gerek ise bu süreçleri yönlendiren iş kurallarında var olan kararları yerine getirmek üzere farklı karar mekanizmaları kullanılır. En eski yüksek seviyeli dil olan Fortran’dan bu yana, if-else’in değişik türleri, switch-case hatta do-while, for  vb. yapılar, programlama dillerinin olmazsa olmaz yapılarındandır.

Cyclomatic complexity, bir metodun karar verme mekanizmalarına yönelik karmaşıklığı ölçmede kullanılan yaklaşımın ismidir. “Cyclo”, Latince’den Ingilizce’ye geçmiş ve çembersellik anlamı veren bir ön ektir. “Cyclomatic” kelimesi ise bir ağdaki, çemberlerin sayısını ifade eder. Bir ağdaki çemberlerin sayısı ise, o ağdaki kenarların sayısından  düğümlerin sayısının çıkarılıp, sonuca bir eklenmesiyle bulunur. Örneğin aşağıdaki grafın cyclomatic complexitysi 10 – 8 + 1 = 3 olarak hesaplanabilir.

Daha kısa olarak aslında, grafdaki kapalı alanların sayısı ile aynı değere ulaşabiliriz. Yukarıdaki şekilde de toplam 3 tane kapalı alan vardır.

Cylomatic complexity kavramını dilimize “karar karmaşıklığı” olarak çevirirsek, aşağıda farklı karar karmaşıklığına sahip üç farklı metodun akışı graf olarak gösterilmiştir.

CycComp

Soldaki ilk metodun karar karmaşıklığı 0, ortadakinin 1 ve sağdakinin ise 5’tir. Tabi olarak bu metotların anlaşılırlığı, kodlanması, test edilmesi vb. konulardaki zorlukları da soldan sağa doğru artmaktadır.

Kodlarımızda karar mekanizmalarını “if-else”, “switch-case”, “for”, “while, do-while” gibi yapılarla ifade ederiz. Yüksek karar karmaşıklığının sebebi, çoğu zaman düzgün soyutlamalar yaptığımızda farklı metot ve sınıflara koyulacak yapıları, bir arada halletmeye çalışmaktır. Strategy, Command, Proxy, State gibi tasarım kalıpları bu duruma çözümdür.

M. Fowler “Refactoring” kitabında bu durum için “Simplifying Conditional Expressions” ismiyle bir bölüm ayırmıştır. Bölümde pek çok öneri yanında karmaşık karar mekanizmalarını tekrar kullanıma izin verecek şekilde ufak-tefek ayrı metotlara koymak gibi teknikler de anlatılır.

Karar ifadelerini gittikçe karmaşıklaşması ve bir sınıftaki hemen her metotta kullanılır hale gelmesine sebep olan bir başka yaygın durum da bir tip hiyerarşisi kurgulamak yerine, tipi gösteren bir değişken ile polimorfik yapılardan kaçınarak kod yazmaktır. Bu durumda, aslında her farklı tipte ifade edilmesi gerek yapıları bol miktarda “if” ya da “switch” ile tek bir metotta halledilir.

public class JavaturkUser{

	private String username; 
	private String password;
        private String name;
	private String lastname;
	private int type;

	public void register(){
		if(type == 1){
			…
		}
		else if(type == 2){
			…
		}
		…
	}
}

Aslolan, JavaTurkUser‘ın miras yapısıyla farklı alt tiplerinin oluşturulması ve register() metodunun her bir tipte override edilerek o tipe uygun bir şekilde tekrar implement edilmesidir.

PMD, karar karmaşıklığı 10’un üzerinde olan yapıların riskli olduğunu söyler ve tekrar düzenlenmesini tavsiye eder.  Yüksek karara karmaşıklığı, uzun metot, muhtemelen de çok parametre demektir. Karar mekanizmalarını doğru yönetebilmek için tasarım şablonlarından ve tek sorumluluk prensibinden faydalanabilirsiniz.

Az kararlı, kısa ve anlaşılır metotlu temiz kodlu günler dilerim 🙂

Bu yazı toplam 815 defa görüntülenmiştir.