Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Bağımlılığın Ters Çevrilmesi Prensibi(Dependency Inversion Principle – DIP)

Bağımlılığın Ters Çevrilmesi Prensibi(Dependency Inversion Principle - DIP)

Merhaba,

Önceki yazılarımda SOLID prensiplerinden STek Sorumluluk Prensibi(Single Responsibility Principle – SRP)‘ni, OAçık Kapalı Prensibi(Open Closed Principle – OCP)L-Liskov’un Yerine Geçme Prensibi(Liskov Substitution Principle – LSP) ve IArayüz Ayrım Prensibi(Interface Segregation Principle – ISP) incelemiştik. Bu içeriğimizde ise sıradaki ve sonuncu olan D harfine denk gelen Bağımlılığın Ters Çevrilmesi Prensibi(Dependency Inversion Principle – DIP) ele alacağız.

Dependency Inversion prensibine göre yazdığımız program soyutlama üzerine dayandırılmalıdır, katılaştırma üzerine değil.

İçeriğimize böyle bir giriş yapmayı uygun gördüm. Bunun sebebi, tasarladığımız kodun bağımlılığı implementation(uygulama) Class’lara değil, Interface’lere olması gerektiğini makalemizin başında vurgulamaktır.

Daha açık bir şekilde ifade etmek gerekirse, üst seviye sınıflar alt seviye sınıf implementasyonlarını değil Interface uygulamalarını kullanmalıdırlar.

Neden mi?
Üst seviyeli işlem yapan sınıflar(High Level Class – Yüksek Dereceli Sınıf), alt seviyeli işlem yapan sınıflara(Low Level Class – Düşük Dereceli Sınıf) bağımlı olmaktadırlar. Bir başka açıdan bakarsak, üst seviyeli işlem yapan metodlar, alt seviyeli işlem yapan metodları kullanmaktadırlar. Haliyle alt seviye metodlarda olası her değişiklik üst seviye metodlarda değişikliğe sebep olması üst seviyenin alt seviyeye bağımlılığını göstermektedir. Haliyle DIP bize bu bağımlılığın ters çevrilmesini prensip edinmemizi önermektedir.

Aşağıda örnek bir bağımlılık senaryosu paylaşılmaktadır.

    class Imalat
    {
        //High Level Class
        public void Olustur()
        {
            Kek kek = new Kek();
            kek.KekYap(true);
        }
    }

    class Kek
    {
        //Low Level Class
        public void KekYap(bool Kakao)
        {
            //Process
        }
    }

Yukarıdaki “Imalat” sınıfı içerisindeki “Olustur” metodu, “Kek” sınıfı içerisindeki “KekYap” isimli metoda bağımlıdır. Bunun sebebi “KekYap”‘ın “Olustur” içerisinde kullanılmasıdır. İlgili metotda yapılacak tüm değişiklikler “Olustur” içerisinde de değişiklik gerektirecektir.

Bağımlılığı aşağıdaki diyagramdan da net bir şekilde görebilmekteyiz.
Bağımlılığın Ters Çevrilmesi Prensibi(Dependency Inversion Principle - DIP)

Nesne tabanlı yaklaşımlarda bu tarz bağımlılıklar soyutlama kullanılarak minimize edilebilmektedirler.

    interface IGida
    {
        void Yap(bool Kakao);
    }

    class Imalat
    {
        //High Level Class
        IGida gida;
        public Imalat()
        {
            gida = new Kek();
        }
        public void Olustur()
        {
            gida.Yap(true);
        }
    }

    class Kek : IGida
    {
        //Low Level Method
        public void Yap(bool Kakao)
        {
            //Process
        }
    }

Yaptığımız bu işlemi aşağıdaki diyagramda ele alalım.
Bağımlılığın Ters Çevrilmesi Prensibi(Dependency Inversion Principle - DIP)
Dikkat ederseniz yaptığımız işlem neticesinde alt seviye sınıfımızı Interface sayesinde soyutlaştırarak, üst seviye sınıfımızda alt seviye sınıfına dair olan bağımlılığı tersine çevirmiş bulunmaktayız. Yani gördüğünüz gibi alt seviye sınıfımız, Interface’e bağımlı bir hale gelmiştir. Ee ilgili Interface’de üst seviye sınıf tarafından refere edildiğinden dolaylı yoldan bağımlılık alt seviyeden üst seviyeye doğru olmuştur diyebiliriz.

Okuduğunuz için teşekkür ederim…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…

Bunlar da hoşunuza gidebilir...

11 Cevaplar

  1. Kerim DEMİRER dedi ki:

    S.a Hocam. Bütün SOLİD prensiplerini okudum. Bunlardan önce de dependency injection konusu ile ilgilenmiştim. Şahsi görüşüm olarak diyorum ki . Her yol dependency injection’a çıkıyor. Temelde bu tasarım desenini anlayıp kavramak SOLİD’i büyük oranda kavramayı sağlar bence. Ve netice olarak SOLİD bize diyor ki.
    Herkes kendi işine baksın kardeşim. Üstünüze vazife olmayan işlere burnunuzu sokmayın sorun çıkmaz diyor.
    Classa sen git sadece kendi işini yap diyor. İnterface ‘a sen git kendi işine bak diyor. Open closed ile sana ne gelenden gidenden sen verilen işi yap diyor sadece. Bence hepsinin özeti dependency injection tasarım deseni. 🙂

  2. veysel dedi ki:

    Tebrik ederim cok harika izahat olmus

  3. Murad dedi ki:

    Merhaba, bunlar ne anlama geliyor aciklarmisiniz rica etsem:

    Üst seviyeli işlem yapan sınıflar(High Level Class – Yüksek Dereceli Sınıf)
    Alt seviyeli işlem yapan sınıflara(Low Level Class – Düşük Dereceli Sınıf)

    yani soyle soyleyim, “Üst/Alt seviyeli işlem yapan sınıflar” derken neyi kast ediyorsunuz? tesekkurler

    • Gençay dedi ki:

      Merhaba,

      Üst seviyeden kasıt operasyon sahası iken, alt seviyeden kastımız ise operasyonun ta kendisidir. Şöyle düşünebilirsiniz ki;
      “Banka” sınıfı üst seviye bir sınıfken, “EFTIslemleri” sınıfı ise alt seviye bir sınıftır ve “Banka” sınıfında yeri ve zamanı geldiğinde çağrılıp kullanılır. Dolayısıyla “Banka” sınıfı “EFTIslemleri” sınıfına bağımlıdır.

      Sevgiler.

  4. Tahir Yıldırım dedi ki:

    Hocam benim anlayamadığım bir husus var alt sınıfta değişiklik yapınca üst sınıfın etkilenmemesi ve üst sınıftaki değişikliğe alt sınıfın uyum sağlaması hususu rica etsem bunu açabilmeniz mümkün mü ?

    Sizin kodda böyle bir düzenleme yaptım DIP hakkında okuduklarımdan anladığım ile sizce doğru mudur ?

        interface IGida
        {
            void Yap(bool Kakao);
        }
    
        class Imalat
        {
            //High Level Class
            IGida _gida;
            public Imalat(IGida gida)
            {
                _gida = gida;
            }
            public void Olustur()
            {
                _gida.Yap(true);
            }
        }
    
        class Kek : IGida
        {
            //Low Level Method
            public void Yap(bool Kakao)
            {
                GidaYap(Kakao);
            }
    
            private void GidaYap(bool Kakao)
            {
                if (Kakao)
                {
                    Console.WriteLine("Kek yapıldı");
                }
                else
                {
                    Console.WriteLine("Kek yapılamadı");
                }
            }
        }
    
  5. Ugur Dundar dedi ki:

    Tersine çevirme doğru bir isimlendirme mi gerçekten.. Yani şimdi Alt Sınıf, Üst Sınıfa öı bağımlı oldu tam olarak.. Aklıma yatmadı 🙂

  1. 09 Mart 2018

    […] Injection(Bağımlılık Enjeksiyonu) Aslında bir tasarım deseni olan ve hatta Dependency Inversion ile prensip haline(SOLİD) gelen Depedency Injection, programatik olarak bağımlılıkları […]

  2. 24 Eylül 2022
  3. 22 Eylül 2023

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir