Dependency Inversion Principle



2 dakikalık okuma
December 21, 2018

Solid yazı dizimizin 5. ve son prensibi olan “Dependency Inversion” prensibine geldik. Tekrar etmekte fayda var. Her prensip birbirinin devamı. Birine uyup diğerine uymayacağım diyemeyiz. Hepsine uyarsak bu iş olur.

Neyse, bu prensibin ortaya çıkma motivasyonu şudur:

  • Birinci ifadeyle: Üst seviye  sınıflar alt seviye sınıflara bağlı olmamalıdır, aralarındaki ilişki abstraction veya interface kullanarak sağlanmalıdır.

  • Başka bir deyişle: Abstraction detaylara bağlı olmamalıdır, aksine detaylar abstraction’lara bağlı olmalıdır.

Şimdi yukarıda ne demek istediğimizi somut bir örnekle izah edelim:

 

class FileLogger {

    public function log() {

        //kodlar

    }

}

 

class DbLogger {

    public function log() {

        //kodlar

    }

}

 


class LogManager {

 

    private $file_logger;

    private $db_logger;

 

    public function __consturct() {

        $this->file_logger = new FileLogger();
        $this->db_logger = new DbLogger();

    }

 

    public function Log() {

        $this->file_logger->log();
        $this->logger->log();
    }

}

 

Yukarıdaki örneğimizi analiz edersek “Dependency Inversion” prensibiyle çeliştiğini görürüz. Çünkü üst seviye sınıfımız olan LogManager, alt seviye sınıflar olan  DbLogger ve FileLogger sınıflarına bağlı.  

İleride patronumuz dese ki slackLogger da ekleyelim. Ne yapacağız? Tutup üst sınıf olan  LogManager sınıfımızı da değiştireceğiz. Oraya da bir kaç şey eklememiz gerekecek yukarıdaki kod mantığında.

Peki bu problemi “Dependency Inversion” nasıl çözeceğiz? Interface oluşturup onun üzerinden işlem yaparak çözeceğiz.Yukarıdaki kodları bu prensibe uyduralım:

 

Interface ILogger {

    public function Log(); 

}

 

class FileLogger implement ILogger 

{

    public function log() { 

    //kodlar

    }

}

 

class DbLogger implement ILogger 

{

    public function log() { 

    //kodlar
    }

}

 

class LogManager {

private $logger;

    public function __consturct( ILogger $logger){

        $this->logger = $logger

    }
 

    public function Log() {

        $this->logger ->log();

    }

}

 

Kullanımı:

$file_log = new LogManager( new FileLogger());
$file_log->log('deneme');
 

$db_log = new LogManager( new DbLogger());
$db_log->log('deneme');

 

Şimdi yukarıdaki örneğe bakarsak üst sınıfımızın alt sınıfa bağlı olmadığını görürsünüz. Şimdi soralım soruyu eğer patronumuz slackLogger da isterse ne olacaktı? hemen slackLogger adında bir sınıf oluşturup ILogger interface’imizinden implement ederiz.

Sonra:

 

$slack_log = new LogManager( new SlackLogger());
$slack_log->log('deneme');

şeklinde kullanırız. Bu işi yaparken üst sınıfımız olan LogManager‘a dokunur muyuz? Hayır.

Cevabımız hayırsa işte size “Dependency Inversion” ile uyumlu bir kod. Hayırlı uğurlu olsun.


Etiketler: