- Published on
Dependency Inversion Principle Nedir ?
- Authors
- Name
- Alperen Önal
Alt Seviye Sınıf ve Üst Seviye Sınıf Nedir ?
Yazımızda bolca geçecekleri için Alt Seviye Sınıf ve Yüksek Seviye Sınıf kavramlarının ne olduklarından kabaca bahsetmek istiyorum.
- Alt Seviye Sınıf : Kullanılan sınıf.
- Yüksek Seviye Sınıf : Alt seviye sınıfı kullanan sınıf.
SOLID prensiplerinin beşinci ve sonuncu prensibi olan Dependency Inversion prensibi 2 ana ilkeye dayanır :
- Yüksek seviyeli sınıflar, düşük seviyeli sınıflar ile doğrudan etkileşim kurmamalıdır. Bunun yerine, her iki seviye de soyutlamalara (interface veya soyut sınıflar gibi) bağımlı olmalıdır.
- Soyutlamalar (abstract) detaylara bağımlı olmamalıdır. Detaylar soyutlamalara bağımlı olmalıdır.
Amaç :
- Kodun esnek ve değiştirilebilir olması sağlanır, çünkü alt seviye sınıfın yüksek seviye sınıfı etkilememesi gerekmektedir.
- Alt seviye sınıf ve yüksek seviye sınıf aralarında soyutlama ile bağlantı kurularak bağımlılığın mümkün olduğunca az olması sağlanır.
Bağımlılığı Ters Çevirme İlkesi (DIP), yüksek seviyeli bir sınıfın daha düşük seviyeli bir sınıfa bağlı olmaması gerektiğini belirtir. Her ikisi de soyutlamalara bağlı olmalıdır. İkincisi, soyutlama ayrıntılara bağlı olmamalı, ayrıntılar soyutlamalara bağlı olmalıdır. kaynak
Aşağıdaki kod örneğimizde SilahAteslemeServisi isimli sınıf, doğrudan Tabanca sınıfına ulaşıp etkileşime geçiyor. Buradan DIP'ın ihlal edildiğini görebiliyoruz.
Buradan şunu da sezebiliyoruz : Tabanca sınıfındaki bir değişiklik doğrudan SilahAteslemeServisi sınıfını etkiliyor ve biz kesinlikle bunu istemiyoruz.
interface ISilah
{
public void AtesEt();
}
class Tabanca:ISilah //alt seviye sınıf
{
public void AtesEt()
{
//ates etme işlemleri
}
//diğer üyeler
}
class SilahAteslemeServisi //yüksek seviye sınıf
{
Tabanca _tabanca;
public void TabancaAtesle(Tabanca tabanca)
{
_tabanca = tabanca;
_tabanca.AtesEt();
}
//diğer üyeler
}
Uygulamamıza Tüfek ile ateş etme seçeneği de eklemek istiyoruz diyelim :
interface ISilah
{
public void AtesEt();
}
class Tabanca:ISilah //alt seviye sınıf
{
public void AtesEt()
{
//ates etme işlemleri
}
//diğer üyeler
}
class Tufek:ISilah //alt seviye sınıf
{
public void AtesEt()
{
//ates etme işlemleri
}
//diğer üyeler
}
class SilahAteslemeServisi //yüksek seviye sınıf
{
Tabanca _tabanca;
Tufek _tufek;
public void TabancaAtesle(Tabanca tabanca)
{
_tabanca = tabanca;
_tabanca.AtesEt();
}
public void TufekAtesle(Tufek tufek)
{
_tufek = tufek;
_tufek.AtesEt();
}
//diğer üyeler
}
Yukarıdaki örnekte olduğu gibi kodumuzun eklenecek her silah sınıfına bağımlı yapıda olması sebebiyle Tüfek eklerken zorluk çektik ve Tufek sınıfına da bağımlı olduk ayrıca diğer SOLID prensiplerini de zincirleme olarak ihlal ettik.
Bunun olmaması için yüksek seviye sınıf olan SilahAteslemeServisi 'nin doğrudan Tabanca, Tufek vb. sınıflarla olan bağlantısını koparmalı ve silah sınıflarına bağımlı kalınmadan kullanabilmek için soyutlama yapmalıyız.
Soyutlama yapacak olursak :
interface ISilah
{
public void AtesEt();
}
class Tabanca:ISilah //alt seviye sınıf
{
public void AtesEt()
{
//ates etme işlemleri
}
//diğer üyeler
}
class Tufek:ISilah //alt seviye sınıf
{
public void AtesEt()
{
//ates etme işlemleri
}
//diğer üyeler
}
class SilahAteslemeServisi //yüksek seviye sınıf
{
ISilah _silah;
public void Atesle(ISilah silah)
{
_silah = silah;
_silah.AtesEt();
}
//diğer üyeler
}
Yukarıda da görebileceğimiz gibi silah soyutlaması yaparak dummy kodlardan ve bağımlılıklardan kurtularak sınıfımızı DIP'e uygun hale getirdik.
Bu örneği tabanca açısından inceleyecek olursak :
Bu durumdan(DIP öncesi) :
Bu duruma getirdik(DIP sonrası) :
SOLID'in son başlığını da böylelikle bitirmiş olduk. Umarım yardımcı olmuştur. Görüşmek üzere.