NDepend ile .NET Uygulamalarının Kod Kalitesini Arttırmak

Merhaba arkadaşlar.

Açıkcası uzun zamandır projelerimizin kod kalitesini artırabilmek için olan, kod analiz tool’ları üzerine bir blog post yazmayı planlıyordum. Fakat bir türlü uygun zamanı bulamadım. Geçtiğimiz günlerde, .NET uygulamalarımızın kod kalitesini geniş bir yelpazede ele alarak, sürekli arttırabilmemize yardımcı olan NDepend tool’unun lisans’ını, free bir şekilde elde edebilme şansını yakaladım.

Bunun için NDepend‘den Patrick’e, ayrıca teşekkür ederim. 🙂

Bu sebeple, bu makale içerisinde NDepend üzerinden ilerleyerek, kod kalitemizi arttırabilmemiz için bizlere neler sunduğunu incelemek ve sizlerle paylaşmak istedim.

Öncelikle, Nedir Bu Kod Kalitesi?

Kaçınılmazdır ki bir çok ortamda biz yazılımcılar genelde, mevcut bir projenin devamlılığını sürdürebilmek ve yeni özellikler ekleyebilmek ile uğraşırız. Bu nedenle mevcut projenin başına geçtiğimiz zaman, genelde vaktiminizin bir çoğunu ise mevcut kodu anlamayabilmek için harcarız. Kaliteli kod dediğimizde ise benim aklıma, diğer yazılımcılar tarafından anlaşılması kolay olan, modüler bir şekilde geliştirilmiş, kolaylıkla yeni özellikler eklenebilen ve değiştirilebilen kod gelmektedir.

Açıkcası kaliteli kodun tek bir sebebi olduğunu söylemek, doğru olmayacaktır. Yazılımda kod kalitesini doğrudan veya dolaylı olarak etkileyen bir çok faktör vardır. Örneğin yazılımcı gözünden bakarsak olaya, bir yazılım geliştirirken hard-coded olarak ilerlemek yerine clean kod yazarak, modüler ve doğru tasarım prensipleri seçenerek uygun çözümü gerçekleştirebilmek, kod kalitesini doğrudan etkileyebilmektedir. Bir başka bakış açısı olan yönetici gözünden bakmak gerekirse de eğer, bir yazılımı geliştirirken izlediğimiz yazılım geliştirme metedolojisi de dolaylı olarak kod kalitesini etkileyebilen bir diğer faktörlerden de birisidir. Bunlara ek olarak yazılımın testlerinin yazılması, dokümantasyonunun yapılması da bir diğer önemli unsurlar arasında yer almaktadır.

Static Kod Analizi

Kod kalitesini arttırabilmenin tek bir yolunun olmadığını söylemiştik. Evet, biz yazılımcılar genelde kod yazma konusunda kendimize oldukça çok güveniriz ve iyi de kod yazarız. 🙂 Fakat, bazı durumlar karşısında gözümüzden kaçan bazı pain point‘ler olabilir. Bu paint point’lere engel olabilmek ve kodumuzda belli bir ölçüde kaliteyi sağlayabilmek için, static kod analiz tool‘larına bu noktada ihtiyaç duyarız. Static kod analiz tool’ları, önceden belirlediğimiz bazı rule’lara göre bizim için kodumuzu incelerler ve kodumuzun kalitesini belirli bir düzeyde tutabilmek için bizlere bazı metrik’ler (Code Coverage, Cyclomatic Complexity, Cohesion vb.) sunarlar.

Benim bu süreçde en çok sevdiğim nokta ise, proje bazlı belirlenebilen rule’lara göre Quality Gate‘lerin oluşturulabilmesidir. Yani, biz henüz source control üzerine kodumuzu commit’lemeden önce yazdığımız kod, belirlediğimiz kalite düzeyininin altında ise, commit’lememize olanak vermemeleridir. Bir çok yazılım geliştirme takımı sevmese de, nihai olarak takımlar içerisindeki bazı tartışmalara da son verebiliyor aslında 🙂

Bu yolda kullanılabilecek bir çok tool var. Ben bugüne kadar çalıştığım şirketlerde StypeCopReSharper ve Sonar ile çalıştım. Bu tool’ların bazıları Visual Studio ile integrated mode’da çalışabilirken, bazıları ise CI süreçlerinde build’lere dahil edilebilmektedir. Bu makale içerisinde ise analysis tool’larından birisi olan NDepend‘i tanıyacağız.

NDepend’i Tanıyalım

NDepend, .NET uygulamalarımızın sağlığını ölçebilmek, sürekli olarak kod kalitesini iyileştirebilmek ve legacy uygulamalarımız üzerindeki refactoring işlemlerini kolaylaştırabilmek için 2004 yılından bu yana olgunlaşmış bir Visual Studio analysis  tool’udur. Hatta kendi değimleri ile .NET proje takımları için bir “Swiss Army Knife” dır. 🙂

Kendi website’lerinde olan açıklamalarına bakarsak ise:

NDepend is a Visual Studio tool to manage complex .NET code and achieve high Code Quality. With NDepend, software quality can be measured using Code Metrics, visualized using Graphs, Matrix and Treemaps, and enforced using standard and custom Rules. Hence the software design becomes concrete, code reviews are effective, large refactoring are easy and evolution is mastered.

NDepend commercial bir analysis tool’udur ve ister Visual Studio integrated mode’da, isterseniz de standalone olarak kullanabilmek mümkündür. NDepend bize kendi tanımlarında da olduğu gibi Code MetricsMatrix ve Treemaps, Standard ve Custom Rule‘larını kullanarak, yazılım kalitesini ölçümleyebilmemize yardımcı olmaktadır. Ayrıca legacy uygulamalarımız için Smart Technical Debt Estimation özelliğini kullanarak, technical-debt’ini ölçümleyebilmeye de olanak sağlamaktadır.

NDepend’in başlıca özelliklerine bakacak olursak:

  • Code Rule and Code Query over LINQ (CQLinq) (Analysis işlemlerini customize edebilmemiz için gayet kullanışlı. Code base’imizi sorgulayabilmemiz için ise, CQLinq adında LINQ tabanlı bir dil sunmaktadır.)
  • Smart Technical Debt Estimation
  • Quality Gates (Özellikle kullanılmalı)
  • Code Quality (82 Code Metrics)
  • Detect Dependency Cycles
  • Complexity and Diagrams
  • In-Depth Issues Management (Technical-debt’i sürekli kontrol altında tutabilmek için gayet kullanışlı)

gibi başlıca özellikleri bulunmaktadır.

Dilerseniz şimdi örnek bir proje üzerinde standalone mode’da çalıştırarak, bir kaç analysis sonucuna bakalım.

NOT: NDepend‘in 14 günlük deneme sürümünü buradan indirebilirsiniz.

İndirmiş olduğumuz paket içerisinden “VisualNDepend” i açalım.

Sol menüden “Analyze VS solutions and VS projects” seçeneğine tıklayalım ve buradan istediğimiz projeyi seçerek, analyze etmek istediğimiz assembly’leri seçelim. Bu işlemin ardından, seçmiş olduğumuz assembly’ler için NDepend bir analyze işlemi gerçekleştirecek.

Analyze işleminin sonucunu ise aşağıdaki gibi bir dashboard üzerinden bize sunmaktadır.

Bu dashboard üzerinden projede ne kadarlık bir debt’e sahibiz, quality gate’i geçebiliyor muyuz, method’larımızın complexity’si ne durumda gibi sonuçları hızlıca görebilmekteyiz. Bunun yanında farketti isek coverage kısmı şuanda boş durumda. Coverage sonucu alabilmemiz için “JetBrains DotCover“, “NCover” ve “Visual Studio” gibi code coverage data’larını import etmemiz gerekmektedir.

Dilerseniz neymiş bu 4 saat 23 dakika sürecek olan %11.94 kısımlık debt bir bakalım. Bunun için öncelikle “Rating” kısmındaki “C” sonucuna tıklayalım.

Sol tarafda açılan menüye bakarsak eğer, hangi class’da kaç issue var ve kaç dakikalık bir efora sahip bilgisini görebilmek mümkün.

Dilersek NDepend‘in yukarıda yer alan LINQ‘ya benzer bir sorgulama dili olan CQLinq ile, sorgu üzerinde bazı değişiklikler yaparak farklı sonuçlar ve gösterimler de elde edebilmek mümkündür.

// Types Hot Spots
from t in JustMyCode.Types
where t.AllDebt() > Debt.Zero && 
      t.AllAnnualInterest() > AnnualInterest.Zero
orderby t.AllDebt().Value.TotalMinutes descending
select new { t, 
   Debt = t.AllDebt(),
   Issues = t.AllIssues(), // AllIssues = {types issues} union {members issues}
   AnnualInterest = t.AllAnnualInterest(),
   BreakingPoint = t.AllBreakingPoint(),
   t.NbLinesOfCode,
   // t.PercentageCoverage,  to uncomment if coverage data is imported
   DebtRating = t.DebtRating(), 
   DebtRatio = t.DebtRatio() 
}

Yukarıda görebildiğimiz gibi LINQ‘ya benzemesi ise biz developer’lar için büyük bir nimet. 🙂

Ayrıca efor bilgilerine ek olarak ne tarz rule’lara takıldığını da görebilmek için, bu sefer dashboard üzerinden %11.94 oranının üzerine tıklayalım.

Tekrardan sol menüye baktığımızda ise hangi rule’lara takıldığımızı görebilmek mümkün. Bu noktada benim hoşuma giden kısım ise ilgili rula’a çift tıklayıp detayına gittiğimde, hangi class içerisinde değişiklik yapacağımı göstermesi ve tekrar tıkladığımda Visual Studio içerisinde açmasıdır.

Bunlara ek olarak aşağıdaki gibi de bir dependency graph’a sahiptir.

Metric’leri ise NDepend, color metric visualization ile bize sunmaktadır. Örneğin: üst menüden “Metrics > Most Coupled > Type” path’ini izleyelim.

Burada ise NDepend, renklendirilmiş visualization’a göre veya sol menüyü kullanarak most coupled durumda olan type sonuçlarını görebilmemizi kolaylaştırıyor.

Build Process Integration

En önemli unsurlardan biriside sanırım NDepend‘in build süreçlerine dahil olabilme konusu. Bir çok zaman, build sürecinde quality gate’leri belirleyebilme ve gerektiğinde build işlemini yarıda kesebilme konuları önemli olmaktadır. NDepend‘i JenkinsTeamCity ve TFS‘e entegre ederek kullanabilmek mümkündür. Ayrıca SonarQube ile de tamamen uyumlu bir şekilde çalışarak, kod kalitesini sürekli olarak iyileştirebilmeyi mümkün kılmaktadır. Ayrıca NDepend issue’ları da, SonerQube issue set’ine import edilebilmektedir. Integration hakkında detaylı bilgiye ise buradan ulaşabilirsiniz.

Sonuç

Açıkcası NDepend‘i bir süredir kurcalıyorum. (Ayrıca “ı” karakterinden kaynaklanan bir problem için NDepend takımı ile beraber çalıştım. Bu problem bir sonraki versiyonda fixlenecek.) Özellikle Visual Studio ile integrated mode’da çalışabilmesi dikkatimi çekti. Çünkü bize geliştirdiğimiz kodu henüz source control’e göndermeden önce kendi local ortamımızda neler olup bittiğini, hangi rule set’lere takıldığımızı görebilmemize olanak sağlıyor ve o şekilde commit yapabilmemize de engel olabiliyor. Bu süreç çalışmakta olduğum şirkette SonarQube plugin’leri ile de denenmişti fakat yanılmıyorsam, efektif bir sonuç alamamıştık. Bunun haricinde uygulamalarımızı sürekli olarak iyileştirip, standardize edilmiş kaliteli kodlar yazabilmemiz için biz .NET developer’ların kullanabileceği güzel bir tool.

https://www.ndepend.com
https://www.ndepend.com/features

Gökhan Gökalp

Recent Posts

Containerized Uygulamaların Supply Chain’ini Güvence Altına Alarak Güvenlik Risklerini Azaltma (Güvenlik Taraması, SBOM’lar, Artifact’lerin İmzalanması ve Doğrulanması) – Bölüm 1

{:tr}Bildiğimiz gibi modern yazılım geliştirme ortamında containerization'ın benimsenmesi, uygulamaların oluşturulma ve dağıtılma şekillerini oldukça değiştirdi.…

8 ay ago

Identity & Access Management İşlemlerini Azure AD B2C ile .NET Ortamında Gerçekleştirmek

{:tr}Bildiğimiz gibi bir ürün geliştirirken olabildiğince farklı cloud çözümlerinden faydalanmak, harcanacak zaman ve karmaşıklığın yanı…

12 ay ago

Azure Service Bus Kullanarak Microservice’lerde Event’ler Nasıl Sıralanır (FIFO Consumers)

{:tr}Bazen bazı senaryolar vardır karmaşıklığını veya eksi yanlarını bildiğimiz halde implemente etmekten kaçamadığımız veya implemente…

2 yıl ago

.NET Microservice’lerinde Outbox Pattern’ı ile Eventual Consistency için Atomicity Sağlama

{:tr}Bildiğimiz gibi microservice architecture'ına adapte olmanın bir çok artı noktası olduğu gibi, maalesef getirdiği bazı…

2 yıl ago

Dapr ve .NET Kullanarak Minimum Efor ile Microservice’ler Geliştirmek – 02 (Azure Container Apps)

{:tr}Bir önceki makale serisinde Dapr projesinden ve faydalarından bahsedip, local ortamda self-hosted mode olarak .NET…

2 yıl ago