Kod metrikleri (Code Metrics) yazılan kodun daha iyi anlaşılması ve yönetilebilmesi için kullanılan kaliteli kod yazmayı hedefleyen yazılım ölçümleridir.

Kod metrikleri ile;

  • Projede kullanılan methodların ve/veya tiplerin hangilerinin yeniden kullanıldığını (reusability) ve test edilmesi gerektiğini anlayabilir,
  • Projede çıkabilecek muhtemel riskleri belirleyebilir,
  • Projenin gidişatı hakkında daha somut bir bilgi edinebilir,
  • Projenin "%50'si bitti..." yerine, sorumlu olduğunuz proje yöneticisine daha istatiksel bilgiler vererek gerçeğe yakın sonuçlar çıkartabilirsiniz.

Kısacası yazdığınız kodun analizini yapabilirsiniz...

Kodun analizi, yazılım geliştiricinin yol haritasındaki checkpoint'lerdir desek yanlış olmaz herhalde. Nasıl bir uygulamayı debug ederken, doğru çalışıp çalışmadığını test ediyorsak, kod analizi ile de kodun doğruluğunu, verimliğini ve yönetilebilirliğini test etmiş oluyoruz.

Yazdığınız koda hakim olmak, kodun gerekli olan yerinde method/sınıf oluşturmak önemlidir. Eğer sadece içinde bir tip barındıran bir sınıf oluşturup (Örneğin int deger; alanı içeren tek bir sınıf) bu sınıfı sadece bir yerde kullanıyorsanız, kodu analiz ettiğinizde (ki kendi bakış açınızla) boyle bir sınıfa ihtiyaç olmayacağını anlayabilirsiniz. Yine programınızın karar süreçlerinde IF,For,While,Foreach gibi karar yapılarını kullanırken bunları verimli kullanmakta önemlidir. Bir methodda iç içe geçmiş 4 tane If yapısı varsa bu koda tekrar bakılmalıdır. Çünkü her If bloğuna girdiği zaman program karar verme sürecine girer ve buda uygulamanızın yavaşlamasına neden olacaktır. Bunlar kaliteli kod yazmanın sadece birkaç senaryosu aslında.

Özetle, kod analizini yapmamızdaki amaç; kaliteli kod yazmak ve kodun yönetilebilirliğini sağlamak. Eğer yazdığınız kod tekrar kullanılabiliyorsa, kod üzerinde yaptığınız bir yerdeki değişiklik diğer yerlerde çok fazla değişiklik gerektirmiyorsa (uygulamaya göre değişir) yazılan kodun kaliteli olduğunun göstergelerinden bir tanesidir.

Bir sonraki yazımda Code Quality ile ilgili bir yazı yazmayı düşünüyorum. Burada kodumuzun kaliteli ve güvenilir olmasının projeye olan katkısından ve yine bizlere yazılım geliştiricisine olan faydalarını sizlere aktarmış olacağım. Ama ilgilenenler için bu konuda yazılmış bir kitap var, Code Quality: The Open Source Perspective. Kitapta geliştiriciler tarafından yazılan kodun sadece müşteri tarafından istenen işlevsel gereksinimlerden başka bir de kodun sistemin gerektirdiği diğer güvenlik, yönetilebilirlik, dayanıklılık gibi direk işlevsellikle ilgili olmayan özelliklerininde yapılması gerektiğini ve bunların nasıl yapılacağını içeren bilgiler mevcut. Ayrıca MSDN'de Code Quality ile ilgili yazılar var, buraya tıklayarak göz atabilirsiniz.

Visual Studio 2008 Team Suite ve Team Developer edition ile beraber gelen Code Metrics aracı yazılan kodun analizi yapılabiliyor. Yukarıda belirtilen kavramları bu aracı kullandıkça daha iyi anlayacağınızı düşünüyorum. Code Metrics ile VS2008'de 5 çeşit kod analizi yapabiliyoruz. Bunlar;

  1. Lines of Code
  2. Class Coupling
  3. Depth of Inheritance
  4. Cyclomatic Complexity
  5. Maintainability Index

Code Metrics, Visual Studio Team Suite için geliştirilmiş bir araç. Malesef Express ve Professional editionlarda bu özellik yok. 

1- Lines of Code

Toplam yazılan kod satırı, çalışabilir (executable) kod parçalarından bahsediyoruz. Yazılan kod, kaynak dosyasındaki kodlara göre değil IL (Intermediate Language) koduna göre baz alınıyor. Boşluklar, commentler, açılış-kapanış parantezleri, üye elemanların,tiplerin ve namespacelerin tanımlamarı bunların dışındadır. Düşük sayı olması iyi çünkü eğer büyük olursa bir method ya da tip kendine yüklenen işten daha fazla iş yapıyor olabilir. Böyle bir durumda yapılan işin bölünmesi gerekir.

codemetrics_lineofcode

Ne zaman kullanılmalı ?

Bir sınıf ya da method'un iş yükünü belirlemek/anlamak için. Eğer method ya da tip kendine yüklenilenden daha fazla iş yapıyorsa ayrılmalıdır.

Ne zaman kullanılmamalı?

  • Projenin, programlamadaki ilerlemesi/gidişatı (Programming Progress)

Çok fazla kod, projenin iyi gittiğini ya da projenin zamanında, belirlenen bütçe ve kapsamda biteceğini göstermez.

  • Geliştiricinin Üretkenliği (Productivity of Developer)

Aynı işi iki faklı kişi farklı sayıda kod ile yazabilir. Örneğin; Biri veritabanı bağlantısını 3 satırda yazarken diğeri 20 satırda yapabilir. Önemli olan sadece kod yazmak değil işlevselliktir. Bir iş için gereken kod, iki farklı geliştirici tarafından farklı yollardan yapılabilir. Biri code generator kullanırken diğeri copy/paste ile bu işlemi yapabilir.

  • Proje hakkındaki tahminler

Yukarıdaki bilgiler ile de görülüyorki, yazılan kodun sayısı önemli değil, işlevsellik önemlidir. Projenin zamanının, kapsamının ve gerekli kaynakların tahmininde yazılan kod satır sayısı bir ölçüt olmamalı.

2- Class Coupling

Class coupling’i bir sınıfın bağlı olduğu sınıfların sayısı olarak nitelendirebilirz. İyi bir yazılım tasarımında, benzer işleri yapan sınıf ve methodlar birbirine bağımlı, diğer sınıflardan mümkün olduğunca bağımsız olmalıdır. (High cohesion - low coupling)

Primitive ve built-in tipler için yani string,int,double bu sayıya dahil edilmez. Sayı yüksek olursa sınıf diğer sınıflara bağlıdır ve bağlı olduğu sınıfta yapılan değişiklik ana sınıfı etkileyecektir. Düşük olması bu sınıfın tekrar kullanılabilirliğini (reusability) gösterir.

codemetrics_classcoupling

Örneğin yukarıdaki tasarımda Account sınıfının coupling'i 2 olarak görülüyor. Account sınıfı hem Order hem de Address sınıflarına bağımlıdır. Bu iki sınıfta yapılan değişiklikler Account sınıfını etkileyecektir. Tasarımınızı yaparken birbirine bağlı sınıflardan mümkün olduğunca kaçınmak, tasarımın stabil halde olmasını sağlar. Stabil derken aslında, yukarda da bahsettiğimiz gibi, bağlı olan sınıfta yapılan değişiklik ile ana sınıfın patlamaması ya da en az değişiklik yapılması idealdir

3- Depth of Inheritance

Depth of Inheritance yani kalıtımdaki derinlik sayısını belirtir. Mesela Object sınıfından türeyen bir sınıfın kalıtım derinliği 1 dir. Proje ve namespace bazında düşündüğümüz zaman bu sayı, o proje ya da namespace içindeki en yüksek kalıtım derinligini belirtir. Bir arayüzü(interface) implement eden sınıflar için bu derinlik düşünülmez.

Derinliğin artması büyük projelerde bazen kodun anlaşılabilirliğini azaltır. Çünkü bir method çok üst seviyelerdeki bir sınıfta tanımlanabildiği için alt seviyelerde bir sınıfta tekrar tanımlanması ya da ezilmesi (override) durumunda tasarımın karmaşıklığı artar. Kodun yönetilebilirliği ve sınıflar arası bağımlılık (low coupling) açısından bu sayının düşük olması idealdir. Bazı kaynaklar bu sayının en fazla 6 olması gerektiğini söyler..

codemetrics_depthofinheritance

Yukarıdaki tasarımda Combobox ve LinkLabel sınıflarının kalıtım derinliği 4 iken, Component sınıfın kalıtım değeri 1 dir.

4- Cyclomatic Complexity

Kodun yapısal karmaşıklığını ölçen metod düzeyinde bir metriktir. Programımızdaki akış kontrolleri ve karar noktalarından baz alınarak hesaplanır. If blokları, switch caseler,do, while,for ve foreach bunlara örnektir.

Her bir karar noktasında ve akış kontrolünde sayı 1 arttırılır. Eğer kodumuz çok karmaşıksa yani çok fazla for ,foeach, if-else yapıları varsa bu sayı yüksek çıkıcaktır ve dolayısıyla daha çok test gerekecektir. Düşük sayı olması iyidir. Bazı kaynaklar bir method için bu sayının 20'nin altında olması gerektiğini belirtir.

codemetrics_cyclomatic

  5- Maintainability Index

Kodun bakım kolaylığı, yönetimi ve sürdürülebilirliği ile alakalıdır. 0 ile 100 arasında bir değer ile gösterilir. Namespace ve assembly seviyesinde baktığımızda, o namespace veya assembly içindeki kodun ortalama maintainability indexi gözükür.

Bu metrikte diğer metriklere göre ters orantı vardır. Eğer diğer metriklerdeki sonuçlar düşük çıktıysa ki ideali budur, bu metrik değeri yüksek çıkar. Kodunuzun ne kadar iyi olduğunu gösteren bir metrik diyebiliriz.

Kodun karmaşıklığı fazla ise bu değer düşük olur ve yönetilmeside zor olur. İdeali yüksek olması. Hesaplarnırken diğer metrikler göz önünde tutulur. (cyclomatic complexity, lines of code gibi)

Visual Studio'daki simgeler ile kodunuzun maintainability index'ini anlayabilirsiniz. Yeşil, sarı ve kırmızı simgeler kodunuzun durumunu özetler. Yeşil, kodun yönetilebilir olduğunu hedeflenen düzeyde olduğunu belirtirken. Sarı ve Kırmızı, kodun sorunlu yerleri olduğunu belirtir.

 codemetrics_maintainabilityindex

Visual Studio'da çalışırken projenize sağ tıklayıp "Calculate Code Metrics" dediğinizde "Code Metrics Results" penceresi karşınıza çıkacaktır. Bu pencerede yukarıda belirtilen metriklerin değerleri ve projenizdeki namespace,library,sınıf ve methodlarınızdaki metrik değerleri gözükecektir. İsterseniz filtreleme yaparak kodun analizini yukarıda anlattığım 5 metrike göre yapabilirsiniz. Ayrıca bu filtrelemeyi yaparken Min ve Max değerlerini vererek sonuçlar üretebilirsiniz.

codemetrics

Aşağıda BlogEngine için yapılmış bir kod analizi var. Yazılan kodun hakkını vermişler sanırım :)

codemetrics_blogengine

Kod analizi yaparken, Code Metrics kodu yazılmamış sınıflarıda değerlendiriyor. Örneğin aşağıdaki analizde, UrlRewrite methodunun içinin doldurulmaması Maintainability Index değerini etkiliyor.

codemetrics_blogengine1

Visual Studio Team Suite ve Team Developer Edition ile gelen Code Metrics bize yazdığımız kodun analizini çıkarırken, kodun kaliteli ve yönetilebilir mi olduğunu yukarıda anlattığım 5 metrik ile gösteriyor. Bu arada unutmadan, bu kod analizinin sonuçlarını Excel'e de atabiliyorsunuz. Daha da güzel bir özellikte şu, bu analize göre Work Item oluşturarak gerekli iyileştirmelerin yapılmasını içeren bir Task oluşturabilirsiniz.

Kod analizi, özellikle kurumsal projelerde kullanılması gereken, çoğu zaman ise zamandan kazanım için kullanmadığımız çok önemli bir aktivite. Bu analiz aracını kullandığımız vakit kodun daha yonetilebilir ve tekrar kullanılabilir hale geldiğini, ama kullanmadığımız takdirde her an her yerde sorun çıkabilecek bir sistemle yaşadığınızı unutmayın.