Kolumne: Quality Time

Kolumne: Quality Time

Tobias Schlitt


Das „Dependency Inversion Principle“ (D) beschreibt eine der wichtigsten Grundlagen der objektorientierten Anwendungsentwicklung: das Verstecken von Komplexität hinter der Fassade von Abstraktionen. Der Text des Prinzips gliedert sich in zwei Teile, die grob umrissen Folgendes besagen: a) Module auf höheren Ebenen sollten keine Abhängigkeiten auf Module niedrigerer Ebenen haben, sondern beide sollten von Abstraktionen abhängen. b) Abstraktionen sollten nicht von Implementierungsdetails abhängen, sondern die Details von der Abstraktion.Wie so oft hilft ein praktisches Beispiel, um diesen theoretischen Zusammenhang besser zu erläutern (Listing 1).Listing 1class NewsLoader{ public function __construct(GoogleNewsService $newsService, Logger $logger ) { $this->newsService = $newsService; $this->logger = $logger; } public function fetchNews( $offset = 0, $limit = null ) { // ... $this->logger->log( 'Fetched news.' ); // ... $this->logger->writeToFile(); }}class NewsLoader{ public function __construct(GoogleNewsService $newsService, Logger $logger ) { $this->newsService = $newsService; $this->logger = $logger; } public function fetchNews( $offset = 0, $limit = null ) { // ... $this->logger->log( 'Fetched news.' ); // ... $this->logger->writeToFile(); }}Es liegt also zum einen eine direkte Abhängigkeit auf ein Modul unterer Ebene vor (GoogleNewsService), zum anderen scheint die Abstraktion des Loggers von den Details einer FileLogger-Implementierung abzuhängen. Zwei Inkarnationen desselben Problems: fehlende oder falsche Abstraktion.Die Auswirkungen solcher Abhängigkeiten auf Details wirken sich auf beiden Modulebenen aus: Zum einen wird das Austauschen des Loggers durch eine andere Implementierung erschwert – alle weiteren Implementierungen müssen sich an das vom FileLogger vorgeschriebene API halten, auch wenn sie die entsprechenden Methoden gar nicht benötigen, oder, noch schlimmer, gar nicht bereitstellen können. Auf der anderen Seite muss bei jeder Verwendung des Loggers darauf geachtet werden, die entsprechende Methode zum eigentlichen Schreiben aufzurufen. Das macht die Verwendung des Loggers unnötig kompliziert und führt einen wichtigen Beweggrund hinter der Objektorientierung ad absurdum: Statt Komplexität hinter der Fassade von Objekten zu verstecken und die Verwendung auch komplizierter Funktionalitäten einfach darzustellen, werden unnötig Details an den Verwender weitergereicht.Besser wäre im gezeigten...

Kolumne: Quality Time

Kolumne: Quality Time

Tobias Schlitt


Das „Dependency Inversion Principle“ (D) beschreibt eine der wichtigsten Grundlagen der objektorientierten Anwendungsentwicklung: das Verstecken von Komplexität hinter der Fassade von Abstraktionen. Der Text des Prinzips gliedert sich in zwei Teile, die grob umrissen Folgendes besagen: a) Module auf höheren Ebenen sollten keine Abhängigkeiten auf Module niedrigerer Ebenen haben, sondern beide sollten von Abstraktionen abhängen. b) Abstraktionen sollten nicht von Implementierungsdetails abhängen, sondern die Details von der Abstraktion.Wie so oft hilft ein praktisches Beispiel, um diesen theoretischen Zusammenhang besser zu erläutern (Listing 1).Listing 1class NewsLoader{ public function __construct(GoogleNewsService $newsService, Logger $logger ) { $this->newsService = $newsService; $this->logger = $logger; } public function fetchNews( $offset = 0, $limit = null ) { // ... $this->logger->log( 'Fetched news.' ); // ... $this->logger->writeToFile(); }}class NewsLoader{ public function __construct(GoogleNewsService $newsService, Logger $logger ) { $this->newsService = $newsService; $this->logger = $logger; } public function fetchNews( $offset = 0, $limit = null ) { // ... $this->logger->log( 'Fetched news.' ); // ... $this->logger->writeToFile(); }}Es liegt also zum einen eine direkte Abhängigkeit auf ein Modul unterer Ebene vor (GoogleNewsService), zum anderen scheint die Abstraktion des Loggers von den Details einer FileLogger-Implementierung abzuhängen. Zwei Inkarnationen desselben Problems: fehlende oder falsche Abstraktion.Die Auswirkungen solcher Abhängigkeiten auf Details wirken sich auf beiden Modulebenen aus: Zum einen wird das Austauschen des Loggers durch eine andere Implementierung erschwert – alle weiteren Implementierungen müssen sich an das vom FileLogger vorgeschriebene API halten, auch wenn sie die entsprechenden Methoden gar nicht benötigen, oder, noch schlimmer, gar nicht bereitstellen können. Auf der anderen Seite muss bei jeder Verwendung des Loggers darauf geachtet werden, die entsprechende Methode zum eigentlichen Schreiben aufzurufen. Das macht die Verwendung des Loggers unnötig kompliziert und führt einen wichtigen Beweggrund hinter der Objektorientierung ad absurdum: Statt Komplexität hinter der Fassade von Objekten zu verstecken und die Verwendung auch komplizierter Funktionalitäten einfach darzustellen, werden unnötig Details an den Verwender weitergereicht.Besser wäre im gezeigten...

Neugierig geworden?


    
Loading...

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang