Yazılım Kalitesi

Bilişim sektöründeki yazılım maliyetlerinin büyümesiyle birlikte, yazılımda kalite kavramı günümüzde üzerinde en çok çalışılan konulardan biri haline gelmiştir. Yazılım dünyasında kalite, kavram olarak herkesin hissedebildiği ancak neticede tam olarak tanımlayamadığı soyut ve sübjektif bir olgu olarak karşımıza çıkmaktadır. Bu disiplin içerisinde kalitenin tam olarak tanımlanabilmesi için gelişmiş ölçme araçlarına ve sağlıklı karşılaştırmalar için tanımlı referans noktalarına ihtiyaç vardır. Ancak yazılım sektöründe bu iki olgu henüz çok gelişmemiş durumdadır.

Yazılım kalitesi temelde müşteri gözünden ve yazılım üreticisi gözünden olmak üzere iki farklı bakış açısıyla ele alınabilir. Müşteriler genel olarak satın aldıkları yazılımların kolay kullanılabilir, hatasız, tüm istekleri karşılayan ve yeterli performansa sahip olmasını isterler. Buna karşılık yazılım üreticileri ise geliştirme ve bakım maliyetlerinin düşük ve üretilen yazılım parçalarının bir sonraki projelerde de kullanılabilir olmasını isterler.
ISO 9126, kalite kavramını ürün temelli olarak müşteri gözünden ele alan ve sınıflandıran uluslar arası bir standarttır. ISO 9126’ya göre kalite sınıfları şunlardır:

  • İşlevsellik: Yazılımın ihtiyaçları karşılama becerisi olarak tanımlanmaktadır. Uygunluk, doğruluk, birlikte çalışılabilirlik ve güvenlik konuları bu sınıf altında incelenmektedir.
  • Güvenilirlik: Yazılımın düzgün çalışma halini muhafaza edebilme becerisi olarak tanımlanmaktadır. Olgunluk, hata toleransı ve geri kurtarma konuları bu sınıf altında incelenmektedir.
  • Kullanılabilirlik: Yazılımın kullanım kolaylığı sağlayan yetenekleri olarak tanımlanmaktadır. Öğrenebilme, anlaşılabilirlik, işletilebilirlik ve kullanıcı etkileşimi konuları bu sınıf altında incelenmektedir.
  • Verimlilik: Yazılımın ihtiyaç duyulan ölçüde yeterli performansla çalışabilme becerisi olarak tanımlanmaktadır. Zaman ve kaynak kullanımı konuları bu sınıf altında incelenmektedir.
  • Bakılabilirlik: Yazılımın değişiklik veya düzeltme isteklerine adaptasyon yeteneği olarak tanımlanmaktadır. Değiştirilebilirlik, test edilebilirlik, analiz edilebilirlik ve bağışıklık konuları bu sınıf altında incelenmektedir.
  • Taşınabilirlik: Yazılımın çalıştığı ortam değişikliklerine uyum sağlayabilme yeteneği olarak tanımlanmaktadır. Adaptasyon yeteneği, yüklenebilirlik özellikleri, ortam değiştirme imkânı ve diğer yazılımlarla uyum konuları bu sınıf altında incelenmektedir.

Üretilen bir yazılımın müşterilerine bakan dış özellikleri iç özelliklerinin bir yansımasıdır. Nesneye dayalı yazılımlarda bağımlılık, uyumluluk ve karmaşıklık yazılımın en önemli iç özellikleridir. En genel anlamda bağımlılık, yazılım parçaları arasında karşılıklı bağımlılığın derecesini, uyumluluk yazılım parçalarının kendi yaptıkları işlerdeki tutarlılığın derecesini, karmaşıklık ise yazılımın içyapısının kavranmasındaki zorluğun derecesini belirtir. Kaliteli yazılımların uyumluluğunun yüksek, karmaşıklığının ve bağımlılığının düşük olduğu yaygın olarak kabul görmüş bir olgudur.

Matematiksel olarak, nesneye dayalı bir yazılımda, bir nesne X = (x, p(x)) seklinde gösterilebilir. Burada x nesnenin tanımlayıcısı, p(x), nesnenin sonlu sayıdaki özelliklerinin belirtir. Nesnenin nitelik değişkenleri ve metotları nesnenin özelliklerini oluştururlar. Mx metotlar kümesi, Ix nitelik değişkenleri kümesi olmak üzere nesnenin özellikleri p(x) = {Mx} U {Ix} şeklinde gösterilebilir.

  • Bağımlılık (Coupling) 

    Ontolojik terminolojide, bağımlılık iki nesneden en az birinin diğerine etki etmesi olarak tanımlanır. A nesnesinin B nesnesine etki etmesi, B’nin kronolojik durumlarının sırasının A tarafından değiştirilmesidir. Bu tanıma göre Ma’nın Mb ya da Ib üzerinde herhangi bir eylemi, aynı şekilde Mb’nin Ma ya da Ia üzerinde eylemi, bu iki nesne arasında bağımlılığı oluşturur.Aynı sınıfın nesneleri aynı özellikleri taşıdıklarından, A sınıfının B sınıfına bağımlılığı aşağıdaki durumlarda oluşur.

    • A sınıfının içinde B sınıfı cinsinden bir üye (referans, işaretçi ya da nesne) vardır.
    • A sınıfının nesneleri B sınıfının nesnelerinin metotlarını çağırıyordur.
    • A sınıfının bir metodu parametre olarak B sınıfı tipinden veri (referans, işaretçi ya da nesne) alıyordur ya da geri döndürüyordur.
    • A sınıfının bir metodu B sınıfı tipinden bir yerel değişkene sahiptir.
    • A sınıfı, B sınıfının bir alt sınıfıdır.

    Bir sınıfın bağımlılığı; işleri için başka sınıfları ne kadar kullandığı, başka sınıflar hakkında ne kadar bilgi içerdiği ile ilgilidir. Yüksek bağımlılık aşağıdaki sorunlara yol açmaktadır.

    • Bir sınıftaki değişim ana bağımlı diğer sınıfları da etkiler. (maintability)
    • Bağımlı sınıfları birbirinden ayrı olarak anlamak zordur. (understandibility)
    • Bağımlı sınıfları tekrar kullanmak zordur. (reusability)
  • Uyumluluk (Cohesion) 

    Bunge benzerliği σ(), iki varlık arasındaki özellik kümesinin kesişimi olarak adlandırılmaktadır. Benzerliğin bu genel tanımından yola çıkarak metotlar arasındaki benzerliğin derecesi, bu iki metot tarafından kullanılan nitelik değişkenleri kümesinin kesişimi olarak tanımlanmaktadır. Elbette metodun kullandığı nitelik değişkenleri metodun özellikleri değildir ama nesnenin metotları, kullandığı nitelik değişkenlerine oldukça bağlıdır.σ(M1,M2), M1 ve M2 metotlarının benzerliği, {Ii} = Mi metodu tarafından kullanılan nitelik değişkenleri olmak üzere σ(M1,M2) = {I1} n {I2}’dir.Metotların benzerlik derecesi, hem geleneksel yazılım mühendisliğindeki uyumluluk kavramı ile hem de kapsülleme ile ilişkilidir. Metotların benzerlik derecesi, nesne sınıfının uyumluluğunun başlıca göstergesi olarak kabul görülebilir. Uyumluluk bir sınıftaki metot ve niteliklerin birbirleriyle ilgili olmasının ölçüsüdür. Bir sınıftaki metot parametrelerindeki ve nitelik tiplerindeki güçlü örtüşme iyi uyumluluğun göstergesidir. Eğer bir sınıf aynı nitelik değişkenleri kümesi üzerinde farklı işlemler yapan farklı metotlara sahipse, uyumlu bir sınıftır. Eğer bir sınıf birbiri ile ilgili olmayan işler yapıyorsa, birbirleriyle ilgili olmayan nitelik değişkenleri barındırıyorsa veya çok fazla iş yapıyorsa sınıfın uyumluluğu düşüktür.

  • Karmaşıklık (Complexity) 

    Karmaşıklık, sınıfların iç ve dış yapısını, sınıflar arası ilişkileri kavramadaki zorluğun derecesidir. “Bir nesnenin karmaşıklığı bileşiminin çokluğudur. Buna göre karmaşık bir nesne çok özelliğe sahip olur. Tanımdan hareketle (x, p(x)) nesnesinin karmaşıklığı özellik kümesinin kardinalitesi yani |p(x)| olur.

Düşük Kaliteli Kod Göstergeleri

Yazılım yaşam döngüsü boyunca sürekli değişim halindedir. Bu değişiklikler bazen dağınık kodları toparlama bazen de uygulamanın yapısını değiştirme şeklinde olabilir. Yazılım geliştiriciler, kod üzerinde değişiklik yaparken kalitesizlik göstergelerini fark ederek gerekli düzeltmeleri yapmalıdırlar. Bu göstergelerin büyük bir çoğunluğu metrik değerlerini olumsuz yönde değiştirirken, bazıları metriklerle analiz sırasında gözden kaçabilir. Kalitesiz kod göstergeleri kavramı ilk olarak, Martin Fowler tarafından var olan kodların iyileştirilmesi için ortaya koyulmuştur. Aşağıda düşük kaliteli kod göstergelerinden bazıları verilmiştir.

  • Tekrar Eden Kod Parçaları: Aynı kod parçasının birden çok yerde gözükmesidir. Bu kod parçalarının metot haline getirilmesi tavsiye edilir. Tanımlanan metriklerle bu tasarım kusurunu fark edecek bir yöntem bulunmamaktadır.
  • Uzun Metot: Nesneye dayalı programlarda metotların kısa olması yeğlenir. Ağırlıklı metot sayısı metriklerinde, ağırlık ölçüsü olarak metodun kod uzunluğu alınırsa, bu kusur fark edilebilir.
  • Büyük Sınıf (God Class): Çok fazla iş yapan, çok sayıda üye nitelik değişkeni veya kod tekrarı bulunduran sınıflar büyük sınıflardır. Bu sınıfların yönetimi zordur. Uyumluluk metrik değeri düşük, bağımlılık metrik değeri yüksek olan sınıfların büyük sınıf olma ihtimali yüksektir.
  • Uzun Parametre Listesi: Uzun parametre listelerinin anlaşılması, kullanımı zordur ve ileride yeni verilere erişilmek isteneceğinden sürekli değişiklik gerektirir. Uzun parametre listesi olan sınıfların metotlar arası uyumluluk metrikleri genellikle düşük çıkar.
  • Farklı Değişiklikler (Divergent Change): Farklı tipte değişiklikler için kodda tek bir sınıf üzerinde değişiklik yapılmasıdır. Bu tasarım kusurunu tanımlanan metriklerle tespit etmek oldukça zordur. Ancak bu özelliğin bulunduğu sınıfın uyumluluk metriğinin düşük çıkması beklenir.
  • Parçacık Tesiri (Shotgun Surgery): Bir değişiklik yapılması gerektiğinde kodda birçok sınıfta küçük değişiklik yapılmasının gerekmesidir. Böyle bir durumda önemli bir değişikliğin atlanma ihtimali yüksektir. Parçacık tesiri tespit edilen sınıflarda karmaşıklık ve bağımlılık metriğinin yüksek olması beklenir.
  • Veri Sınıfı: Sadece veriler ve bu verilerin değerlerini okumak ve yazmak için gerekli metotları barındıran ve başka hiçbir iş yapmayan sınıflardır. Tanımlanan metriklerle bu tür kusurları bulmak çok kolay gözükmemektedir. Ancak sınıfın açık ve gizli metotlarının oranı bu konuda yardımcı olabilir.
  • Reddedilen Miras: Türetildiği sınıfın sadece küçük bir parçasını kullanan sınıflar bu durumu oluştururlar. Bu kalıtım hiyerarşisinin yanlış olduğunun bir göstergesidir.

Tasarım Kalıpları

Tasarım kalıpları ilk olarak mimar Christopher Alexander tarafından kaliteli mimari yapılardaki ortak özelliklerin sorgulanması ile ortaya çıkmıştır. C. Alexander yaptığı araştırmalar sonucunda beğenilen yapılarda benzer problemlerin çözümünde benzer çözüm yollarına başvurulduğunu belirlemiş ve bu benzerliklere tasarım kalıpları adını vermiştir.

Yazılım dünyasında bu konudaki ilk önemli çalışma kendilerine dörtlü çete (Gang of Four) adı takılan dört yazar tarafından ortaya konmuştur. GoF tasarım kalıpları olarak adlandırılan çalışma üç gruptan oluşmaktadır.

  • Yaratımsal Kalıplar 

    Bu gruptaki kalıplar nesne yaratma sorumluluğunun sınıflar arasında etkin paylaştırılması ile ilgilidir. Tekil Nesne (Singleton), Soyut Fabrika (Abstract Factory), İnşacı (Builder) kalıplarının yer aldığı bu grup, nesne yaratmanın getireceği ek karmaşıklıkları ve bağımlılıkları en aza indirirken, sınıfların uyumluluğunu yüksek tutmayı amaçlamaktadırlar.

  • Yapısal Kalıplar 

    Bu gruptaki kalıplar, sınıf ve nesnelerin kompozisyonu ile ilgilidir. Genel olarak ara yüzler oluşturmak için kalıtımdan faydalanırlar ve yeni işlevler kazandırmak için nesnelerin yapılarını oluşturacak uygun yöntemler önerirler. Adaptör (Adapter), Köprü (Bridge) ve Ön Yüz (Facade) bu gruptaki bazı kalıplardır.

  • Davranışsal Kalıplar 

    Bu kalıplar özellikle nesneler arasındaki iletişimle ilgilidir. Bu kalıplar aracılığı ile yazılım, ihtiyaçlara göre kolayca genişletilebilir, hataların yerleri daha çabuk tespit edilebilir. Bu gruptan sıkça başvurulan kalıplar ise Gözlemci (Observer) ve Strateji (Strategy)’dir.

Aşağıda bazı sık kullanılan tasarım kalıpları açıklanmıştır.

  • Adaptör (Adapter) 

    İstenen işi yapan fakat farklı ara yüzleri olan benzer birimler için tek bir kararlı ara yüz oluşturulmak isteniyorsa adaptör kalıbı kullanılır.
    adaptör

  • Fabrika (Factory) 

    Nesnelerin yaratılmasında karmaşık kararlar vermek gerekiyorsa ve uyumluluğu arttırmak için nesne yaratma işleminin diğer işlemlerden ayrı ayrılması isteniyorsa fabrika kalıbı kullanılır.
    fabrika
    Fabrika sınıfı o andaki kıstaslara göre aynı üst sınıftan (interface) türeyen sınıflar arasından hangisini yaratacağına karar vererek yarattığı sınıfın adresini üst sınıf değişkeni ile geri döndürür.

  • Tekil Nesne (Singleton) 

    Bir sınıftan sadece tek bir nesne yaratılması ve bu nesnenin diğer nesnelere global tek bir erişim noktası sağlanması isteniyorsa tekil nesne kalıbı kullanılır.tekilnesneSınıf içinde kendi tipindeki nesnelere işaret edebilen statik bir değişken ve sınıf nesnelerini yaratan yine statik bir metot eklenir. Sınıf dışında bu sınıftan bir nesne üretilmemesi için kurucu metot özel (private) yapılır.

  • Stateji (Strategy) 

    Bir sınıfın belli bir konudaki davranışının o sınıftan yaratılan bir nesnenin yaşamı süresince defalarca değişmesi istenebilir. Birbiriyle ilgili olan fakat farklılık gösteren bu davranışların gerçeklenmesi için strateji kalıbı kullanılır.strateji
    Bu tasarım kalıbında her davranış aynı ara yüzden türeyen ayrı birer sınıf olarak gerçeklenir.

  • Bileşik Nesne (Composite) 

    Bir nesnenin belli bir iş için tek bir nesne (atomik nesne) ile ilişkilendirilebildiği gibi birden fazla nesne grubu (bileşik nesne) ile ilişkilendirilmesi de isteniyor, esnekliği sağlamak için ilgili nesnenin o iş tek bir nesne ile mi yoksa bir nesne grubuyla mı ilişkili içinde olduğundan habersiz olması isteniyorsa bileşik nesne kalıbı kullanılır.BileşikNesneAtomik ve bileşik nesneler, aynı ara yüzden türetilerek bileşik nesne içerisine atomik nesneleri içeren bir liste yerleştirilir.

  • Ön Yüz (Facade) 

    İleride değişme olasılığı bulunan ve bazı alt parçaları kullanılmak istenen, değişik ara yüzlere ve yapılara sahip hizmetleri içeren bir alt sistem ile bağlantı kurulmak isteniyorsa ön yüz kalıbı kullanılır.ÖnyüzAlt sistem ile bağlantıyı sağlayan bir ön yüz nesnesi tanımlanarak, bu nesne içine kullanıcı sistemin gerek duyduğu işleri yapan metotlar yerleştirilir. Kullanıcı sistem bu metotları çağırdığında metotların içinde alt sistemin gerekli yerlerine erişilir.

  • Gözlemci (Observer) 

    Değişik tipteki abone nesnelerinin yayıncı nesnelerindeki durum değişikliklerini sezmesi ve bu değişimlere kendilerine göre tepki göstermesi isteniyorsa gözlemci kalıbı kullanılır.Gözlemci

    Abone nesneleri ortak bir ara yüzden türetilir. Yayıncı nesne isteyen aboneleri kendi listesine kayıt eder. Yayıncı nesne kendi durumunda bir değişiklik olduğunda listesindeki abonelere durumu iletir.

  • Köprü (Bridge) 

    Soyutlama ve gerçeklemenin bir arada ilişki içinde kullanılması ve olası değişikliklerden sistemin en az etkilenmesi isteniyorsa köprü kalıbı kullanılır.Köprü

    Farklı türlerdeki soyutlama ve gerçekleme sınıfları kendi içlerinde ortak bir ara yüzden türetilerek soyutlama sınıfının gerçekleme sınıfına işaret eden bir işaretçiye sahip olması sağlanır. Çalışma anında her soyutlama nesnesi kendi işlemini gerçekleştirmek için sahip olduğu işaretçinin gösterdiği gerçekleme nesnesi ile mesajlaşır.

  • Dekoratör (Decorator) 

    Bir nesnenin davranışı bir dizi işlemden oluşuyor ve işlemlerin sayısı ve sırası çeşitli koşullara göre değişiyorsa dekoratör kalıbı kullanılır.
    DekoratörTüm alt işlemler ortak bir ara yüzden türeyen ayrı bir dekoratör sınıfı olarak tasarlanır. Programın çalışması sırasında, dekoratör sınıflardan oluşturulan nesneler istenilen sırada bir listeye eklenir.

İlgilerin Ayrıştırılması (Separation of Concerns)

İlgilerin ayrıştırılması bir yazılımın aynı alana yönelik işlerini gerçekleştiren parçalarının ortak bir çatı altında toplanması şeklinde tanımlanır.

  • Modül Düzeyi İlgiler
    Bir modülün temel olarak yapması gereken işler.
  • Sistem Düzeyi İlgiler
    Loglama, hata kontrolü, yetki denetimi gibi bütün sistem tarafından ihtiyaç duyulan görevler.

Sistem düzeyi ilgilerin bütün modüllerden çağırılması (modül düzeyi ilgileri dik kesmesi) bağımlılığı (coupling) arttırarak kod karıştırmaya (code tangling) yol açar. Aynı zamanda bir yöntem içinde sistem düzeyi ilgilere olan bağlantı arttıkça uyumluluk (cohesion) düşer ve bu da kod dağıtmaya (code scattering) neden olur.

Cepheye Yönelik Programlama (AOP – Aspect Oriented Programming)

Yazılımı ilgi düzeyinde ele alarak nesne yönelimli programlama metodolojisinin çözüm üretmekte zorlandığı dik kesen ilgiler (cross-cutting concerns) konusuna çözüm getiren bir yaklaşımdır. Nesne yönelimli programlamanın yerine geçmeyip onu geliştirilecek bir adım olarak ortaya çıkmıştır.

  • Sınıf (Class)
    OOP teknikleri ile gerçeklenmiş ve sistemin ana işlevini (modül düzeyi ilgiler) tanımlayan yapılardır.
  • Cephe (Aspect)
    AOP teknikleri ile gerçeklenmiş ve sistemdeki dik kesen ilgilerin (sistem düzeyi ilgiler) gerçeklendiği yapılardır.

Ayrı olarak gerçeklenmiş olan sınıf ve cephe bileşenlenleri örme (weaving) işlemi ile birleştirilerek bütünsellik sağlanır.

weaving

Cepheye Yönelik Programlama Elemanları

  • Birleşme noktası (Join point) 
    Örme işleminin sınıf üzerinde belirli hangi noktalarda yapılabileceğini belirten işaretşilerdir.
  • Kesim noktası (Pointcut)
    Birleşme noktalarını kullanarak örme şleminin gerçekleşme koşulunu tanımlayan yapılardır.
  • Tavsiye (Advice)
    Sınıf üzerinde tanımlanan birleşme noktalarında, örme işlemine katılarak yapılması istenen işlerlerdir.

aop

Chidamber&Kemerer Metrik Kümesi

Sınıfın Ağırlıklı Metot Sayısı (Weighted Methods per Class – WMC)

Bir sınıfın tüm metotlarının karmaşıklığının toplamıdır. Tüm metotların karmaşıklığı 1 kabul edilirse, sınıfın metot sayısı olur. Sınıfın metotlarının sayısı ve metotlarının karmaşıklığı, sınıfın geliştirilmesine ve bakımına ne kadar zaman harcanacağı hakkında fikir verebilir. Metot sayısı çok olan taban sınıflar, çocuk düğümlerde daha çok etki bırakırlar; çünkü tanımlanan tüm metotlar türetilen sınıflarda da yer alacaktır. Metot sayısı çok olan sınıfların uygulamaya özgü olma ihtimali yüksektir. Bu nedenle tekrar kullanılabilirliği düşürürler.

Kalıtım Ağacının Derinliği (Depth of Inheritance Tree – DIT)

Sınıfın kalıtım ağacının köküne olan uzaklığıdır. Hiçbir sınıftan türetilmemiş olan sınıflar için bu değer 0’dır. Kalıtım hiyerarşisinde daha derinde olan sınıflar, daha çok metot türettiklerinden davranışlarını tahmin etmek zordur. Derin kalıtım ağaçları daha çok tasarım karmaşıklığı oluşturur.

Alt Sınıf Sayısı (Number of Children – NOC)

Sınıftan doğrudan türetilmiş alt sınıfların sayısıdır. Eğer bir sınıf çok fazla sayıda alt sınıfa sahipse, bu durum kalıtımın yanlış kullanıldığının bir göstergesi olabilir. Bir sınıfın alt sınıf sayısı, sınıfın tasarımdaki potansiyel etkisi hakkında fikir verir. Çok alt sınıfı olan sınıfların metotları daha çok test etmeyi gerektireceğinden bu metrik, sınıfı test etmek için harcanacak maliyet hakkında bilgi verir.

Nesne Sınıfları Arasındaki Bağımlılık (Coupling Between Object Classes – CBO)

Sınıfın bağımlı olduğu sınıf sayısıdır. Bu metrikte, bir sınıf içinde nitelik ya da metotlar diğer bir sınıfta kullanılıyorsa, iki sınıf arasında bağımlılık olduğu kabul edilmiştir. Sınıflar arasındaki aşırı bağımlılık modüler tasarıma zarar verir ve tekrar kullanılabilirliği azaltır. Bir sınıf ne kadar bağımsızsa başka uygulamalarda o kadar kolaylıkla yeniden kullanılabilir. Bağımlılıktaki artış, değişime duyarlılığı arttıracağından, yazılımın bakımını zorlaştırır. Bağımlılık aynı zamanda tasarımın farklı parçalarının ne kadar karmaşık test edileceği hakkında fikir verir. Bağımlılık fazla ise testlerin daha özenli yapılması gerektiğinden test maliyetleri artacaktır.

Sınıfın Tetiklediği Metot Sayısı (Response For a Class – RFC)

Verilen sınıftan bir nesnenin metotları çağırıldığında, bu nesnenin tetikleyebileceği tüm metotların sayısıdır. Bu metrik sınıfın test maliyeti hakkında da fikir verir. Bir mesajın çok sayıda metodun çağrılmasını tetiklemesi, sınıfın testinin ve hata ayıklamasının zorlaşması demektir. Bir sınıftan fazla sayıda metodun çağırılması, sınıfın karmaşıklığının yüksek olduğunun işaretçisidir.

Metotların Uyumluluğu (Lack of Cohesion in Methods – LCOM)

Bu metriğin birden çok tanımı olmakla birlikte ilk kez kullanılanı şu şekildedir: C1 sınıfının M1, M2, …, Mn metotları olduğunu ve {li} kümesinin de Mi metodunda kullanılan nitelik değişkenleri kümesi olduğunu kabul edelim. Bu durumda LCOM bu n kümenin kesişiminden oluşan ayrık kümelerin sayısıdır. Daha sonra bu tanım yenilenerek şu şekle getirilmiştir: P hiçbir ortak nitelik değişkeni paylaşmayan metot çiftlerinin kümesi, Q en az bir ortak nitelik değişkeni paylaşan metot çiftlerinin kümesi olsun. Bu durumda LCOM, |P| > |Q| ise |P|-|Q|, aksi halde 0 olur. Bunlarla birlikte literatürde farklı tanımlar da mevcuttur. Sınıfın uyumluluğunun düşük olması, sınıfın iki veya daha fazla alt parçaya bölünmesi gerektiğini gösterir. Düşük uyumluluk karmaşıklığı arttırır, bu nedenle geliştirme aşamasında hata yapma ihtimali yükselir. Ayrıca metotlar arasındaki ilişkisizliklerin ölçüsü sınıfların tasarımındaki kusurların belirlenmesinde de yardımcı olur.

Brito e Abreu MOOD Metrik Kümesi

Metot Gizleme Faktörü (Method Hiding Factor – MHF)

Sistemde tanımlı tüm sınıflardaki görünür (çağrılabilir) metotların, tüm metotlara oranıdır. Bu metrikle sınıf tanımının görünürlüğü ölçülür. Burada kalıtım ile gelen metotlar hesaba katılmamaktadır.

Nitelik Gizleme Faktörü (Attribute Hiding Factor – AHF)

Sistemde tanımlı tüm sınıflardaki görünür (erişilebilir) niteliklerin, tüm niteliklere oranıdır. Bu metrikle sınıf tanımının görünürlüğü ölçülür Burada kalıtım ile gelen metotlar hesaba katılmamaktadır.

Metot Türetim Faktörü (Method Inheritance Factor – MIF)

Sistemde tanımlı tüm sınıflardaki kalıtım ile gelen metot sayısının, tüm metotların (kalıtımla gelenler dâhil) sayısına oranıdır.

Nitelik Türetim Faktörü (Attribute Inheritance Factor – AI)

Sistemde tanımlı tüm sınıflardaki kalıtım ile gelen niteliklerin, tüm niteliklere (kalıtımla gelenler dâhil) oranıdır.

Çok Şekillilik Faktörü (Polymorphism Factor – PF)

Bir C sınıfı için sistemdeki farklı çok şekilli durumların, maksimum olası çok şekilli durumlara oranıdır. Bilindiği gibi türetilen nitelikler ve metotlar alt sınıflarda yeniden tanımlanarak, ana sınıftaki metotları örtebilir (override).

Bağımlılık Faktörü (Coupling Factor – CF)

Sistemde sınıflar arasında var olan bağımlılık sayısının, oluşabilecek maksimum bağımlılık sayısına oranıdır. Burada kalıtımla oluşan bağımlılıklar hesaba katılmamaktadır.

Bansiya ve Davis QMOOD Metrik Kümesi

QMOOD metrikleri, Bansiya ve Davis tarafından yazılımın toplam kalite endeksi hesaplanması için 4 seviyeden oluşan hiyerarşik bir model içinde tanımlanmıştır. En alt seviyede sınıf, metot gibi nesneye dayalı yazılım bileşenleri vardır. 3. seviyede QMOOD metrikleri vardır. QMOOD metriklerinden, karmaşıklık, uyumluluk gibi bir üst seviyedeki yazılım özellikleri hesaplanır. Bu yazılım özelliklerinden de anlaşılabilirlik, esneklik, tekrar kullanılabilirlik gibi en üst seviyedeki kalite nitelikleri hesaplanır. Son olarak kalite niteliklerinden toplam kalite endeksi hesaplanır. QMOOD çalışmasında tanımlanan seviyeler ve bağlar aşağıda gösterilmiştir.

qmood

Ortalama Ata Sayısı (Avarage Number of Ancestors – ANA)

Tüm sınıfların DIT (Kalıtım Ağacının Derinliği – Depth of Inheritance Tree) değerlerinin ortalamasıdır. Metrik değeri yazılımda soyutlamanın kullanımını gösterir.

Metotlar Arası Uyumluluk (Cohesion Among Methods – CAM)

Metotların imzaları arasındaki, benzerliğin ölçüsüdür. Tam tanımı Bansiya’ nın metrik kümesi çalışmasında yer almamaktadır. Literatürde metotların imzalarına bakarak uyumluluk ölçen farklı metrik tanımları bulunmaktadır. Bunlar temelde metotların parametre kullanım matrisi üzerinde çalışırlar ve imzalardaki uyumluluğu tam uyumlu olmaya yakınlıkla kıyaslayarak ölçerler. Metotlar ve tüm parametreler numaralandırılır, i. metodun imzasında, j. parametre kullanılıyorsa, matriste Mij 1 aksi halde 0 olur. CAMC parametre matrisindeki 1 sayısına bakarken, NHD matris satırları arasındaki Hamming uzaklıklarına bakar. SNHD ise NHD metriğinin olası en küçük ve büyük değerine göre ölçeklenmiş halidir.

Sınıf Arayüz Boyutu (Class Interface Size – CIS)

Sınıfın açık (public) metotlarının sayısıdır ve yazılımın mesajlaşma özelliği hakkında fikir verir.

Veri Erişim Metriği (Data Access Metric – DAM)

Sınıfın özel (private) ve korumalı (protected) niteliklerinin tüm niteliklere oranıdır. Bu metrik yazılımın kapsülleme özelliğini gösterir.

Doğrudan Sınıf Bağımlılığı (Direct Class Coupling – DCC)

Bir sınıfı parametre olarak kabul eden sınıfların sayısı ile bu sınıfı nitelik değişkeni olarak barındıran sınıfların sayısının toplamıdır. Sınıfın bağımlılığı bu metriğe bakarak anlaşılabilir.

Kümeleme Ölçüsü (Measure Of Aggregation – MOA)

Kullanıcı tarafından tanımlanmış sınıf bildirimlerinin, tanımlı temel sistem veri tiplerine (int, char, double vs… ) oranıdır.

İşlevsel Soyutlama Ölçüsü (Measure of Functional Abstraction – MFA)

Sistemde tanımlı tüm sınıflardaki türetilmiş metot sayısının, tüm metot sayısına (türetilmiş metotlar dâhil) oranıdır. Yazılım kalıtım özelliği bu metrikle belirlenir.

Metot Sayısı (Number of Methods – NOM)

Sınıfta tanımlı metot sayısı tüm metotlar bir birim kabul edilirse WMC metriği ile aynı değeri taşır. Sınıfın metot sayısı sınıfın karmaşıklığının bir göstergesidir.

Yardımcı Araçlar

FindBugs (http://findbugs.sourceforge.net/)

Maryland üniversitesi tarafından geliştirilmiş açık kaynaklı bir statik kod analiz aracıdır. Yazılımın mevcut Java kodu üzerinde çeşitli analizler yaparak, yaygın yazılım hatalarını ve tasarım kusurlarını otomatik olarak kısa sürede bulabilmektedir. Findbugs; java, netbeans, jboss gibi günümüzde popüler olan birçok programın geliştirme aşamalarında da etkin şekilde kullanılmaktadır.

Metrics (http://metrics.sourceforge.net/)

Eclipse projesine bir eklenti olarak geliştirilen açık kaynak kodlu bir başka programdır. Eclipse geliştirme ortamındaki Java projelerine, tümleşik biçimde çalışabilen program, yaygın kullanılan birçok yazılım metriğini otomatik olarak ölçerek geliştiriciye raporlamaktadır. Statik fonksiyon sayısı, türeme derinliği, bağımlılık, fonksiyon karmaşıklığı, soyutlama adedi gibi metrikler bunlardan yalnızca birkaçıdır. Metrics programı aynı zaman yazılımdaki bağımlılıkları grafiksel olarak gösterme yeteneğine de sahiptir. Bu sayede geliştiricilerinin yazılımdaki bağımlıkları görsel olarak daha iyi analiz edebilmeleri mümkün olmaktadır. Aşağıda Metrics programı ile üretilmiş örnek bir çıktı verilmiştir.

Metrics

PMD (http://pmd.sourceforge.net/)

PMD bir statik kod analiz aracıdır. Java kodları üzerinde çalışan bu program mevcut kod üzerinde otomatik analizler yaparak olası kusurları; kullanılmayan, tekrarlanmış ve gereksiz kod parçalarını hızlıca bulmaktadır.

Coverlipse (http://coverlipse.sourceforge.net/)

Gerçekleme yani yazılım kodu ile gereksinimler ve test senaryolarının arasındaki örtüşme ilişkilerini inceleyen açık kaynak kodlu bir Eclipse eklentisidir. Program yazılım geliştirmenin bu üç temel aşaması arasındaki örtüşme ilişkilerini analiz ederek aradaki boşlukları ortaya çıkartmaktadır. Dolayısıyla unutulmuş bir gereksinime veya test edilmemiş bir yazılım parçasına yer vermemeye yardımcı olmaktadır.

CheckStyle (http://checkstyle.sourceforge.net/)

Yazılımın yapısından çok formatı ile ilgilenen bir açık kaynak kodlu yazılım aracıdır. Mevcut Java kodlarının üzerinde format analizi yaparak geliştiricilerin kod yazım standartlarına uyumlu çalışmalarına yardımcı olmaktadır. Kurumun kendi yazım standartlarını da oluşturabileceği bu yazılımda, aynı zamanda genel kabul görmüş kimi uluslararası yazım standartları da mevcuttur.

SDMetrics (http://www.sdmetrics.com/)

Kod üzerinde değil de UML tasarım dokümanları üzerinde çeşitli görsel ve sayısal analizler yapabilen ticari bir programdır. Program, tasarım aşamasından yani geliştirme aşaması başlamadan yazılımın tasarımını analiz ederek bağımlılık ve karmaşıklığa dair birçok uygunsuzluğu ortaya çıkartabilmektedir. Bu aşamada yapılacak erken tespitlerin maliyet açısından da kazanımları büyük olabilmektedir.

SD Metrics

Coverity (http://www.coverity.com/)

Java’nın yanı C++ ve C program kodları üzerinden çalışabilen ticari ve oldukça kapsamlı bir kod analiz aracıdır. Analiz sonuçlarının yanı sıra bazı otomatik düzeltmeler de yapabilen program yazılım dünyası tarafından çok büyük maliyetli ve kapsamlı projelerde kullanılmaktadır. Bu programın diğer bir önemli özelliği de, statik analizin yanı sıra çalışma esnasında dinamik analizleri de yapabilmesidir. Aşağıda Coverity programı ile üretilmiş örnek bir bağımlılık grafiği verilmiştir.

Coverity

Visul Studio Kod Metrikleri (Code Metrics)

Kod metrikleri, Visual Studio içinde yer alan kaynak kodları incelemek ve çeşitli ölçülere göre yazılımı derecelendirmek için kullanılan matematiksel ve istatistiksel yöntemlerdir. Kod metrikleri, bir projenin sınıflarını, modüllerini ve namespacelerini, çeşitli ölçülerle değerlendirerek potansiyel sorun kaynaklarını vurgular.

  • Lines of Code
  • Class Coupling
  • Depth of Inheritance,
  • Cyclomatic Complexity
  • Maintainability Index

Kod Metrikleri, Solution Explorer’da bir projeye veya solution üzerine sağ tıklayıp “Calculate Code Metrics” diyerek veya Analyze menüsünden “Calculate Code Metrics For Solution / Project” ile hesaplanabilir.

Codemetrics

Lines of Code

Lines of Code, bir metoddaki işletilebilir kod satır sayısını gösterir. Alfabe dışı karakterler, commentler, tip ve namespace tanımları bu hesaplamanın dışında kalır. Çok yüksek bir değer, bir tipin veya metodun çok fazla iş yaptığı, bu yüzden de bölünmesi gerektiği anlamına gelir.

Lines of code

Class Coupling

Bu metrik; sınıf seviyesinde, parametreler, yerel değişkenler, dönüş tipleri, method çağırımları, generic ilklemeler, base sınıflar, arayüz implementasyonları vb. aracılığıyla diğer sınıflarla olan bağlantı sayısını ölçer. Kısaca bu metrik bir sınıfın bağlı olduğu sınıf sayısını gösterir. Bu sayının mümkün olduğunca az olması beklenir. Çünkü yüksek coupling değerleri, bir tasarımın diğer sınıflara bağımlılıkları yüzünden, yeniden kullanılmasının ve bakımının güç olduğu anlamına gelir.
classcoupling

Depth of Inheritance

Kalıtım derinliği, bir sınıfın, kalıtım ağacında o sınıfın üst düğümünden köke kadar olan sınıfların sayısını gösterir. Hiyerarşi ne kadar derinleşirse, hangi metodların veya alanların nerelerde tanımlandığını veya yeniden tanımlandığını takip etmek de zorlaşır. Çok derin kalıtım ağaçları, uygulamanın testinin ve bakımının karmaşıklığını arttırır.
Depth of Inheritance

Cyclomatic Complexity

Cyclomatic Complexity programdaki birbirinden farklı kod akışlarının sayısıdır. Daha basitçe açıklamak gerekirse, programdaki karar noktaları olan if bloklarının, do, while, foreach ve for döngülerinin ve switch case bloklarının sayısıdır. Yüksek cyclomatic completixy değerine sahip olan kodların test ve bakımı zor olmaktır. Çünkü bu kodlarda test edilebilecek çok sayıda farklı akış vardır.

Cyclomatic Complexity

Cyclomatic Complexity(CC) değerini hesaplamak için aşağıdaki gibi basit bir yol izlenebilir.

  1. Metodun akışına CC= 1 değeri ile başla.
  2. Her bir if,while,repeat, for, and , or anahtar kelimeleri veya eşdeğerleri için CC’ye 1 ekle
  3. Switch’teki her bir case için CC’ye 1 ekle

Metodlar için cyclomatic complexity değerleri ve riskleri belirtilmiştir. Cyclomatic complexity değeri ne kadar yüksekse metodun karmaşıklığı da o kadar fazladır.

cyclomatic complexity tablo

Maintainability Index

Sınıf üyeleri veya tipler seviyesinde kod bakımının kolaylığına gösteren bu değişken 0-100 arasında bir değer alır. Bu değerin yüksek olması programın sürdürebilirlik seviyesinin yüksek olduğu anlamına gelir. Namespace veya assembly seviyesindeki maintainability index, o namespace veya assembly içerisindeki bütün tiplerin maintainability indexlerinin ortalamasıdır. Bu metrik, Halstead Volume, Cyclomatic Complexity ve Lines of Code metrikleri bir araya getirilerek oluşturulmuştur. Halstead Volume, kullanılan işlenen (operand) ve işlemcilerin (operator) sayısıyla ilgili bir metriktir. Maintainability index için kullanılan denklem aşağıda verilmiştir.

—MI = 171 – 5.2 * log2 (HV) – 0.23 * (CC) – 16.2 * log2 (LOC)

—HV: Halstead Volume
—CC: Cyclomatic Complexity
LOC: Lines of Code

Maintainability index, kolay bir gösterimi olması için ikonlarla ifade edilmiştir. İkonlar için, değer aralıkları ve sürdürebilirlik seviyeleri aşağıdaki gibidir.

maintainability index

Kaynaklar

1. U. Erdemir, U.Tekin, F.Buzluca, “Nesneye Dayalı Yazılım Metrikleri ve Yazılım Kalitesi” Yazılım Kalitesi ve Yazılım Geliştirme Araçları Sempozyumu (YKGS08), İstanbul, 2008.

2. Doç Dr. Feza Buzluca, İTÜ, BLG468E Object-Oriented Modeling and Design ders notları  http://ninova.itu.edu.tr/tr/dersler/bilgisayar-bilisim-fakultesi/2097/blg-468e/ekkaynaklar/

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

%d blogcu bunu beğendi: