IT-Berufe-Podcast

Dependency Inversion Principle (DIP) – Wissenshäppchen #7


Listen Later

Im siebten Wissenshäppchen geht es um das Dependency Inversion Principle.
Inhalt
Das DIP ist das letzte der fünf SOLID-Prinzipien.
High level modules should not depend upon low level modules. Both should depend upon abstractions.
Oder:
Abstractions should not depend upon details. Details should depend upon abstractions.
Welche Abhängigkeiten werden hier "umgedreht"? Komponenten, die andere Komponenten benötigen, erzeugen sich diese nicht selbst, sondern bekommen sie von außen hineingegeben. Braucht ein Service beispielsweise ein Repository um arbeiten zu können, erzeugt er es sich nicht selbst, z.B. mit this.repo = new Repository() in seinem Konstruktor, sondern bekommt es stattdessen schon fertig als Parameter übergeben, z.B. public Service(Repository repo). Das heißt, obwohl die Abhängigkeit vom Service zum Repository geht, wird sie "umgekehrt" aufgelöst, indem das Repository dem Service übergeben wird.
Erklärung
Wenn Komponenten sich ihre Abhängigkeiten selbst erzeugen, sind diese später nur umständlich oder gar nicht mehr austauschbar.
Tests von Komponenten, die sich ihre Abhängigkeiten selbst erzeugen, sind schwierig/unmöglich/langsam/fehleranfällig, da die Abhängigkeiten nicht so einfach gegen Fake-Objekte ausgetauscht werden können.
Die Abhängigkeiten sind nicht explizit in der API sichtbar. Der obige Service "braucht" ein Repository, aber das sieht man nur, wenn man sich den Quelltext von Service anschaut. Beim Erzeugen eines Services ist dies nicht offensichtlich, weil er sich das Repository "heimlich" selbst erzeugt.
Beispiel
Um alle Employees zu bezahlen, erzeugt sich die Payroll ihr eigenes MySqlEmployeeRepository. Dadurch wird auch im Test die echte Datenbank verwendet und ein Austauschen gegen eine Oracle-Datenbank erfordert eine Anpassung der Klasse Payroll (vgl. Open Closed Principle).
class Payroll
def initialize
@repo = MySqlEmployeeRepository.new
end
def pay_employees
@repo.find_all.each { |employee| employee.pay }
end
end
class MySqlEmployeeRepository
def find_all
puts "Accessing the database and reading all employees"
[Employee.new] * 10
end
end
class Employee
def pay
puts "Thank you for paying me"
end
end
Payroll.new.pay_employees
# Accessing the database and reading all employees
# Thank you for paying me
# ...
# Thank you for paying me
Statt dieser "harten" und versteckten Abhängigkeit sollte Payroll sich lieber die Implementierung eines Repositorys liefern lassen. Das erfordert nur eine kleine Umstrukturierung des Codes und ermöglicht deutlich einfachere Tests.
class Payroll
def initialize(repo)
@repo = repo
end
def pay_employees
@repo.find_all.each { |employee| employee.pay }
end
end
class MySqlEmployeeRepository
def find_all
puts "Accessing the database and reading all employees"
[Employee.new] * 10
end
end
class FakeEmployeeRepository
def find_all
[Employee.new] * 1
end
end
class Employee
def pay
puts "Thank you for paying me"
end
end
puts "Production:"
Payroll.new(MySqlEmployeeRepository.new).pay_employees
puts "Test:"
Payroll.new(FakeEmployeeRepository.new).pay_employees
# Production:
# Accessing the database and reading all employees
# Thank you for paying me
# ...
# Thank you for paying me
# Test:
# Thank you for paying me
Außerdem kann Payroll nun auch ohne Anpassungen (!) mit einer Oracle-Datenbank arbeiten.
class OracleEmployeeRepository
def find_all
puts "Reading employees from Oracle database"
[Employee.new] * 100
end
end
puts "Using Oracle:"
Payroll.new(OracleEmployeeRepository.new).pay_employees
# Reading employees from Oracle database
# Thank you for paying me
# ...
# Thank you for paying me
Vorteile
Abhängigkeiten sind explizit sichtbar und können bei geänderten Anforderungen oder in Tests einfach ausgetauscht werden.
...more
View all episodesView all episodes
Download on the App Store

IT-Berufe-PodcastBy Stefan Macke

  • 5
  • 5
  • 5
  • 5
  • 5

5

1 ratings


More shows like IT-Berufe-Podcast

View all
IQ - Wissenschaft und Forschung by Bayerischer Rundfunk

IQ - Wissenschaft und Forschung

46 Listeners

Eine Stunde History - Deutschlandfunk Nova by Deutschlandfunk Nova

Eine Stunde History - Deutschlandfunk Nova

106 Listeners

c’t uplink - der IT-Podcast aus Nerdistan by c’t Magazin

c’t uplink - der IT-Podcast aus Nerdistan

9 Listeners

ZEIT WISSEN. Woher weißt Du das? by DIE ZEIT

ZEIT WISSEN. Woher weißt Du das?

48 Listeners

Chaosradio by Chaos Computer Club Berlin

Chaosradio

7 Listeners

Computer und Kommunikation by Deutschlandfunk

Computer und Kommunikation

9 Listeners

Smarter leben by DER SPIEGEL

Smarter leben

47 Listeners

Kampf der Unternehmen by Wondery

Kampf der Unternehmen

13 Listeners

kurz informiert by heise online by heise online

kurz informiert by heise online

1 Listeners

Quarks Science Cops by Quarks

Quarks Science Cops

17 Listeners

Terra X History - Der Podcast by ZDF - Terra X

Terra X History - Der Podcast

9 Listeners

Aha! Zehn Minuten Alltags-Wissen by WELT

Aha! Zehn Minuten Alltags-Wissen

29 Listeners

KI verstehen by Deutschlandfunk

KI verstehen

9 Listeners

Wirecard: 1,9 Milliarden Lügen by Süddeutsche Zeitung

Wirecard: 1,9 Milliarden Lügen

3 Listeners

Passwort - der Podcast von heise security by Dr. Christopher Kunz, Sylvester Tremmel

Passwort - der Podcast von heise security

3 Listeners