Yazılım Tasarım Kalitesi Nedir? Yazılım Kalitesi Nedir? Farkları Nelerdir?Öncelikle kalite nedir onu tanımlayalım. Bir ürün, hizmetin belirlenen veya olabilecek ihtiyaçları karşılama kabiliyetine dayanan özelliklerin toplamıdır şeklinde basitçe tanımlanır kalite. Peki bu tanım yeterli midir? Bence hayır. Kalite bakıldığında sezgisel olarak anlaşılabilen ama tanımlanması güç bir kavramdır. Yine de biz tanımlayabildiğimiz kadarı ile yazılım kalitesi ve tasarım kalitesi nedir ele alalım.Yazılım kalitesi bir yazılımın dıştan göründüğü şekliyle ihtiyaçları karşılama kabiliyeti ve özelliklerinin toplamıdır. Yazılımın çalışma, cevap verme süreleri, kullanıcı açısından kullanım kolaylığı, görsel özellikleri, hata verme sıklığı vs. gibi kavramları dışarıdan gözlemlenen unsurlara örnek verebiliriz. Yazılım Tasarım Kalitesi ise yazılım iç özelliklerini temsil eder. Kolay anlaşılır, kolay gerçeklenebilir, kolay değiştirilebilir, kolay test edilebilir bir tasarım yüksek kaliteli bir tasarımdır. Geliştirme, test, hata giderme, bakım maliyetlerini minimuma indiren bir tasarım, yazılım tasarım kalitesinin yüksek olduğunu gösterir. Yazılım tasarım kalitesi, yazılım kalitesini büyük oranda etkilemektedir ancak tasarım kalitesi yüksek, kalitesi düşük bir yazılım veya bunun tersi de mümkündür. Soyut kavram olan yazılım yerine somut bir kavram üzerinden benzetme yapalım; devamı için tıklayınız...
Tasarım Desenleri - Fabrika Metodu (Factory Method)Fabrika metodu yaratıcı desen grubuna girer. Oldukça yaygın kullanılmaktadır. Amacımız, bir nesneyi tanımlamak için bir arabirim veya soyut sınıf tanımlamak ancak hangi sınıftan nesne oluşturulacağı kararını alt sınıflara bırakmaktır.Örneğin aşağıdaki gibi soyut bir enstrüman sınıfı ve bu sınıftan türeyen bazı enstrümanları tanımlayalım. public abstract class Instrument { public virtual void Play() { Console.WriteLine($"{GetType().Name} played."); } } public class BassGuitar : Instrument { } public class ClassicalGuitar : Instrument { } public class Drums : Instrument { } public class ElectricGuitar : Instrument { } public class Keyboard : Instrument { }Daha sonra bu enstrümanları kullanacak olan müzik gruplarını temsil edecek bir soyut sınıf oluşturalım. devamı için tıklayınız...
SOLID Prensipleri Nedir?SOLID prensipleri Robert C. Martin tarafından tanımlanmış ve ismini 5 ana tasarım kuralının baş harflerinden alan tasarım kuralları bütünüdür. Bu beş kuralı aşağıdaki gibi anlatabiliriz.1. Tekil Sorumluluk (Single Responsibility): Bir sınıfın sadece tek bir sorumluluk alanı olması gerekir. Sadece tek bir sebeple değiştirilmeye ihtiyaç duymalı ve üstüne vazife olmayan görevler üstlenmemeli. Basit bir örnek;internal class Rectangle : Shape { private readonly double _a; private readonly double _b; public Rectangle(double a, double b) { _a = a; _b = b; } public override double GetArea() { return _a * _b; } public override double GetPerimeter() { return 2 * (_a + _b); } }Yukarıdaki Rectangle sınıfı dikdörtgeni temsil etmekte ve basitçe alan ve çevre değerlerini dönen fonksiyonlar içermektedir. Aşağıdaki ShapePrinter sınıfı ise bu şeklin alan ve çevre bilgisini yazdırma görevini üstlenmiştir.internal class ShapePrinter { private readonly IShape _shape; public ShapePrinter(IShape shape) { _shape = shape; } public void Print() { Console.WriteLine($"Shape:{_shape.GetType()}, Perimeter:{_shape.GetPerimeter()}, Area:{_shape.GetArea()}"); } }Nereye, nasıl, hangi formatta yazdırılacağı sorumluluğu ShapePrinter sınıfına aittir. Eğer yazdırma fonksiyonunu da Rectangle sınıfı içerisinde gerçekleştirseydik, ilerde Console ile birlikte örneğin dokümana da yazdırmak istediğimizde Rectangle sınıfında da değişiklik yapmamız gerekecekti. Halbuki bu görev Rectangle sınıfı ile ilgili değil. Bu yüzden tekil sorumluluk prensibine uymamış olacaktık.devamı için tıklayınız...
Statik Sınıf Nedir? Ne için Kullanılır?Statik sınıflar, kabaca tüm elemanları statik olan ama kendisi statik olmayan sınıflara denktir. Eğer tüm üyeleri statik olan bir sınıf tanımlamışsak, o sınıfın da statik tanımlanması önünde herhangi bir engel yoktur. Statik sınıfları normal sınıflarla aşağıdaki gibi kıyaslayabiliriz:Statik sınıfStatik olmayan sınıfSadece statik üyeler içerebilir.Nesne örneği (instance) oluşturulamaz. Abstract sınıf özelliği gösterir.Miras alınamaz. Sealed sınıf özelliği gösterir.Statik olmayan yapıcı (constructor) bulunduramaz.Statik ve statik olmayan üyeleri bir arada barındırabilir.Nesne örnekleri oluşturulabilir.Miras alınabilir.Statik ve statik olmayan yapıcı bulundurabilir.devamı için tıklayınız...
Operatör Aşırı Yükleme (Operator Overloading) Nedir?Operatör Aşırı Yükleme, birli (unary) "+, -, !, ~, ++, -- gibi", ikili (binary) "+, -, *, /, %, &, |, ^, <<, >>" ve karşılaştırma "==, !=, <, >, <=, >=" operatörlerinin, bizim tarafımızdan tanımlanmış karmaşık sınıflarda nasıl uygulanacağına dair yeniden tanımlanmasıdır. Basit bir örnek ile anlatacak olursak:public class Matrix2D { private readonly int _rowCount; private readonly int _columnCount; private readonly double[,] _matrix; public double this[int row, int column] { get { return _matrix[row, column]; } set { _matrix[row, column] = value; } } public Matrix2D(double[,] matrix) { _matrix = matrix; _rowCount = matrix.GetLength(0); _columnCount = matrix.GetLength(1); } public override string ToString() { var stringBuilder = new StringBuilder(); for (var i = 0; i < _rowCount; i++) { for (var j = 0; j < _columnCount; j++) { stringBuilder.Append(_matrix[i, j].ToString("F1").PadLeft(5)); stringBuilder.Append(" "); } stringBuilder.AppendLine(); } return stringBuilder.ToString().TrimEnd('\r', '\n'); } }Yukarıda Matrix2D adlı 2 boyutlu matrisleri temsil eden bir sınıf tanımladık. Bu matris sınıfının ikili toplama (+) işlemi için operatör önyüklemesini aşağıdaki şekilde yazabiliriz.public static Matrix2D operator +(Matrix2D matrix1, Matrix2D matrix2) { if (matrix1._rowCount != matrix2._rowCount || matrix1._columnCount != matrix2._columnCount) { throw new NotSupportedException(); } var resultMatrix = new Matrix2D(new double[matrix1._rowCount, matrix1._columnCount]); for (var i = 0; i < matrix1._rowCount; i++) { for (var j = 0; j < matrix1._columnCount; j++) { resultMatrix._matrix[i, j] = matrix1._matrix[i, j] + matrix2._matrix[i, j]; } } return resultMatrix; }Aynı şekilde matris çıkarma (-) işlemi için de aşağıdaki şekilde yazabiliriz. devamı için tıklayınız...
Çoklu Kalıtım (Multiple Inheritance) ve Elmas Sorunu (Diamond Problem)Çoklu Kalıtım, tanım olarak bir sınıfın aynı anda birbirinden bağımsız birden çok sınıftan türeyebilmesini ifade eder. Örneğin, "Nepenthes" sınıfını "Plant" sınıfından türetebileceğimiz gibi "Carnivorous" sınıfından da türetebiliriz. Her bitki etçil olmadığı için bu iki sınıf birbirinden bağımsızdır. İşte bu tarz bir durumda ortaya çıkan çoklu kalıtım özelliğini C++ dili desteklerken, daha modern Java ve C# dilleri desteklememektedir.Esasında Nesne Yönelimli Programlama prensiplerine çok da yakışmayan Çoklu Kalıtım özelliği, modern nesne yönelimli dillerde Elmas Problemi denen bir probleme takılmaktadır. Nedir bu elmas problemi? Örnekleyelim: public class Organism { public virtual void Feed() { Debug.WriteLine("Feeding..."); } } public class Plant : Organism { public override void Feed() { Debug.WriteLine("Doing photosynthesis..."); } } public class Carnivorous : Organism { public override void Feed() { Debug.WriteLine("Eating another organism..."); } } public class Nepenthes : Carnivorous, Plant { } public class SampleRunner { public static void Run() { var nepenthes = new Nepenthes(); nepenthes.Feed(); } }C# ile yukarıdaki gibi sınıflar tanımladığımızda, compiler zaten "Class 'Nepenthes' cannot have multiple base classes: 'Carnivorous' and 'Plant'" hatası verecek ve kodlarımız derlenmeyecektir. Bu hatanın olmadığını varsayıp derlendiğini düşünelim. Bu durumda; Run betiğinde yer alan nepenthes varlığının "Feed" metodu çağırıldığında uygulama alt sınıflardan hangisine ait Feed metodunu çağıracaktır? Görüldüğü üzere Plant ve Organism sınıflarında Feed metodu override edilmiş ve elimizde iki farklı implementasyon var. Uygulamanın hangisini neye göre seçeceği problemi tam olarak elmas problemini anlatmaktadır. (Aşağıdaki gibi elmas şekline benzer bir kalıtım diyagramı probleme adını vermektedir.)devamı için tıklayınız...
Çok Biçimlilik (Polymorphism) Nedir, Ne İşe Yarar?Çok biçimlilik bir nesnenin, kalıtım yoluyla miras aldığı tüm tiplerde görüntülenebilmesi durumudur. Örneğin;public interface IAnimal { void MakeSound(); }Yukarıdaki gibi hayvanı tanımlayan bir arayüz oluşturalım. Arayüz tek bir davranışa (Ses Çıkar) sahip olsun. Aşağıda ise bu arayüzü gerçekleştiren 3 sınıf tanımladık. Kedi, köpek ve köpekten türeyen Husky aynı arayüzü (IAnimal) gerçekleştiriyor.internal class Cat : IAnimal { public void MakeSound() { Debug.WriteLine("Meoww"); } } internal class Dog : IAnimal { public virtual void MakeSound() { Debug.WriteLine("Woof.."); } } internal class Husky : Dog { public override void MakeSound() { Debug.WriteLine("Auwww"); } }devamı için tıklayınız...
Sargable vs Non-Sargable QueriesSargable sorgular, tabloda tanımlı indeksleri kullanarak arama yapabilen sorgulardır. Non-sargable sorgular ise kesinlikle kaçınılması ve mutlaka sargable alternatifinin bulunarak kullanılması gereken, indeks dostu olmayan, çalışma zamanı oldukça yüksek, kalitesiz sorgulardır.Non-Sargable Sorgu: SELECT PER.* FROM dbo.Person PER WHERE SUBSTRING(PER.Name,1,3)= 'Meh' Sargable Alternatifi:SELECT PER.* FROM dbo.Person PER WHERE PER.Name LIKE 'Meh%'Yukarıdaki örnekte ilk sorgu için tüm satırlardaki name kolonu öncelikle substring fonksiyonuna gireceği için indeks özelliğini kaybedecektir. İkinci sorguda ise kolon değerleri herhangi bir ön operasyona maruz kalmadan direkt olarak Sargable LIKE operatörü ile sorgulanmıştır.devamı için tıklayınız...
Yapıcı (Constructor) Nedir?Nesne yönelimli programlama konseptinde yapıcı (constructor), temel öğelerden biridir. Nesnenin yaratılma aşamasında çalışacak olan fonksiyonu tanımlar. Yapıcı, tanımlamadığınız takdirde varsayılan olarak ara seviyede oluşturulacaktır.public class Car { private int velocity; private int gear; private EngineStatus engineStatus; public Car() { velocity = 0; gear = 1; engineStatus = EngineStatus.Stopped; } }Yukarıdaki örnekte, aracın motoru çalışmayan vaziyette, birinci viteste ve hareketsiz olarak oluşturulacaktır.Yapıcı, aşırı yükleme (overloading) özelliğine sahiptir. Ayrıca farklı erişim belirleyiciler (access modifier) ile tanımlanabilir. Aşağıdaki örnekte sınıfa ikinci bir yapıcı izi daha eklenmiştir. Buna göre araç nesnesi, sadece aynı kütüphane içerisinden (internal) erişilmek suretiyle, motor durumu belirtilerek de oluşturulabilir.devamı için tıklayınız...
Nesne Yönelimli Programlama Nedir?Yazılım için oluşturulan sanal yapının gerçek hayatla kolay ilişkilendirilebilmesi için C, SQL, Cobol gibi prosedürel dillere alternatif olarak C++, Java, C# gibi nesne yönelimli programlama amacı taşıyan diller ortaya çıkmıştır. Bu diller ile birlikte, yazılımcılar gerçek dünyadaki nesneleri yazılım dünyasına kolaylıkla yerleştirebilecek, geliştirmeden ziyade tasarıma odaklanacaktır.En iyi kod hiç yazılmamış koddur felsefesine de hizmet eden nesne yönelimli programlama dilleri, prosedürel dillere kıyasla aynı işi daha az kod satır sayısı ile yapabilmektedir. Bununla birlikte sürdürülebilirlik, taşınabilirlik, kullanılabilirlik vb. gibi nitelikleri konu alan yazılım tasarım kalitesi gibi bir alanı da ortaya çıkarmıştır. Nesne yönelimli diller ile yazılan yazılımlar tasarım kalite unsurları açısından da sınanmakta ve birbirleri ile kıyaslanmaktadır.devamı için tıklayınız...