Av: Helena Engström

2019-03-11

Tre tips på hur du implementerar Dependency Inversion

Tycker du att SOLID låter som en jättebra idé i teorin men har lite svårt att förstå hur du ska implementera det i praktiken? Speciellt det där kluriga D:et som Uncle Bob aldrig hinner med när han går igenom kodexempel på sina föreläsningar? I så fall har du kommit rätt. Här kommer tre konkreta tips på hur du får din kod att följa Dependency Inversion Principle.

Definitionen av Dependency Inversion Principle lyder:

High-level modules should not depend on low-level modules. Both should depend on abstractions.
Abstractions should not depend upon details. Details should depend upon abstractions.

Där en high-level modul är en modul som använder sig av andra moduler och en low-level modul är en modul som inte gör det.

Tips 1: Skicka allting uppifrån och ner.

Ta in instanser av de klasser du behöver i konstruktorn istället för att skapa upp nya instanser direkt i din klass. På så sätt har du inverterat beroendet, din (High-level) klass beror inte längre av klasserna den använder. Du skulle kunna skicka in en helt annan klass i konstruktorn om du ville, dvs du är inte längre beroende av den.

Tips 2: Kodar du i ett statiskt språk? Använd interfaces.

För att du helt ska kunna byta ut klasserna som nämndes i tips 1 så behöver konstruktorn ta in en instans som implementerar ett interface, inte en specifik klass. Beroendet mellan den aktuella klassen och klasserna den använder är nu via en abstraktion.

Tips 3: Flytta instansieringen av dina klasser till ett ställe. Eller använd dependency injection.

I tips 1 sa vi att vi alltid ska skicka allting uppifrån och ner, men någonstans måste vi ju göra själva instansieringen. Bäst är att göra alla instansieringar på en specifik plats, förslagsvis som funktioner i en egen fil som exemplet i python nedan. Eller i en statisk klass om du gillar OOP.

#Factory.py
from Person import Person
from Employee import Employee
from Employment import Employment
.
.
.

def createPerson(self):
  return Person()
def createEmployee(self):
  return Employee(self.createPerson())
def createEmployment(self):
  return Employment(self.createEmployee())
.
.
.

Eller om det låter jobbigt så kan du använda dig av Dependency injection istället.
Dependency injection innebär att du sätter upp en konfigurering som håller reda på alla beroenden mellan dina klasser. Antingen genom att koppla interfaces mot konkreta klasser eller genom att mer specifikt säga vilken instans en viss klass ska få i sin konstruktor när den instansieras.

Vill du veta mer så rekommenderar jag Tim Coreys videor om dependency inversion och dependency injection:

#SOLID

Gästbloggare: Hanna Liliemark – vår Hello World!-stipendiat

Övergången från React till React Native