Yazıma başlamadan önce SOLID prensiplerinin avantajlarından bahsetmek istiyorum.
- Esneklik,
- Bakımı Kolay,
- Kod tekrarını önleyebilme,
- Kodun okunabilirliğini artırma,
SOLID prensiplerinin amacı Projeye yeni bir davranış eklendiğinde eklenen davranış önceki davranışları etkilememelidir. Yani yeni eklediğimiz Class’lar metotlar önceki yap Class’ları ve metotları etkilememeli veya çok az etkilemelidir.
Gelelim esas konumuza Dependency Inversion Principle (DIP) nedir?
Üst seviyeli sınıfların alt seviyeli sınıflara doğrudan bağlı olmamasını veya gevşek bağlı olmasını amaçlayan prensip olarak tanımlayabiliriz. Genellikle projelerimizde üst seviyeli sınıflar-metotlar alt seviyeli sınıfları veya metotları içlerinde kullanırlar, alt seviyeli metotlar da herhangi bir geliştirme veya değişiklik yaptığımızda üst sınıfları etkileyecektir işte bu durumlar da Solid’in tam da bu prensibi devreye girmektedir.
Kodun alt yapısını oluştururken sınıfları ve metotları geliştirmeye açık ve üst seviyeli sınıflara gevşek bağlı şekilde oluşturursak işimiz çok daha kolay ve zamandan tasarruf etmiş oluruz.
Bu anlatıklarımızı örneklerle daha anlaşılır hale getirelim.
Log Örneği:
Senaryomuz şu şekilde olsun: Yeni bir Blog sitesi yapımına başlıyoruz ve yöneticimiz Log’ları tutmak için Database kullanacağız yani tüm Log’ları Database kaydedeceğiz dedi. Bizde log ve Article sınıflarımızı metotlarını oluşturup kodumuzu aşağıdaki gibi hazır hale getirdik.
Dependency Inversion Uygulanmayan Kod Örneği:
public class Program
{
static void Main(string[] args)
{
ArticleMnager articleManager = new ArticleMnager();
articleManager.RemoveArticleById(1);
Console.Read();
}
}
public class ArticleMnager
{
DbLogger dbLogger = new DbLogger();
public void RemoveArticleById(int id)
{
Console.WriteLine("Makale Loglama ekranı");
dbLogger.Log();
}
}
public class DbLogger
{
public void Log()
{
Console.WriteLine("Database Logger çalıştı");
}
}
Buraya kadar her şey yolunda geliştirmeyi istediğimiz gibi halletmiş olduk. Ama kodları inceleyecek olursak ArticleManager sınıfımız DbLogger sınıfımıza sıkı sıkıya bağlı olduğu için Dependecy Inversion prensibine uygun kod yazmamış olduk.
Bir müddet sonra yöneticimiz Logları Database de tutmak yavaş ve çok yer kaplıyor biz bunları en iyisi dosyaya yazalım dedi ardından Dosya ya log atma işlemleri için gerekli geliştirmeyi yaptık.
public class ArticleMnager
{
////İlk Başta proje yapılırken Db logger kullandık
//DbLogger dbLogger = new DbLogger();
//Daha sonra istek üzerine Dosya Loglama sınıfını yazdık
FileLogger fileLogger = new FileLogger();
public void RemoveArticleById(int id)
{
Console.WriteLine("Makale Loglama ekranı");
//dbLogger.Log();
fileLogger.Log();
////Başka logger kullanmak istediğimiz de 2 satır sildik 2 satır ekledik. Projenin daha büyük olduğu düşünülürse işin içinden çıkılmaz hal alacaktır.
}
}
public class FileLogger
{
public void Log()
{
Console.WriteLine("Logged by FileLogger");
}
}
Şimdi Aynı senaryoyu Dependency Inversion Prensibine uygun şekilde yazalım.
public class Program
{
static void Main(string[] args)
{
ArticleMnager articleManager = new ArticleMnager(new FileLogger());
articleManager.RemoveArticleById(1);
Console.Read();
}
}
public interface Ilog
{
void Log();
}
public class ArticleMnager
{
public Ilog _log { get; set; }
public ArticleMnager(Ilog log)
{
_log = log;
}
public void RemoveArticleById(int id)
{
Console.WriteLine("Removed Article");
_log.Log();
}
}
public class DbLogger : Ilog
{
public void Log()
{
Console.WriteLine("Database Logger");
}
}
public class FileLogger : Ilog
{
public void Log()
{
Console.WriteLine("Dosya Logger");
}
}
Yukarı da ki gibi kodlarımızı düzenlediğimizde artık Dependency Inversion prensibine uygun bir şekilde yazmış olduk. Görüldüğü üzere ArticleManager sınıfımız FileLogger sınıfına sıkı sıkıya bağlı değildir. Bu şekilde yazarak zamandan ve koddan tasarruf ederek geliştirmeye açık mimari kurmuş olduk.

Yorumlar(2)
Umut
Çok faydalı bir yazı olmuş, tebrikler.
Neslihan Koçak
Çok faydalı bir yazı, teşekkürler...