Sobes.tech
Middle

Wat kun je vertellen over het D-principe in SOLID?

sobes.tech AI

Antwoord van AI

Het Dependency Inversion Principle (DIP) stelt dat:

  • Modules op hoog niveau niet afhankelijk moeten zijn van modules op laag niveau. Beide typen modules moeten afhankelijk zijn van abstracties.
  • Abstracties mogen niet afhankelijk zijn van details. Details moeten afhankelijk zijn van abstracties.

Het doel van de D in SOLID is het loskoppelen (decoupling) van hoog-niveau beleidslijnen van de implementatie op laag niveau. In plaats van dat een hoog-niveau module direct afhankelijk is van de concrete implementatie van een laag-niveau module, vertrouwen beide op een gemeenschappelijke interface of abstracte klasse. Dit verhoogt de flexibiliteit, testbaarheid en onderhoudbaarheid van de code.

In Flutter wordt dit vaak gerealiseerd door het gebruik van abstracte klassen of mixins om contracten te definiëren, die vervolgens door concrete klassen worden geïmplementeerd. Bijvoorbeeld bij het werken met data:

// Abstractie
abstract class DataService {
  Future<List<String>> getData();
}

// Laag-niveau implementatie (concreet detail)
class ApiDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logica voor het ophalen van data via API
    return ['API Data 1', 'API Data 2'];
  }
}

// Andere laag-niveau implementatie (ander concreet detail)
class LocalDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logica voor het ophalen van data uit lokale opslag
    return ['Local Data 1', 'Local Data 2'];
  }
}

// Hoog-niveau module die afhankelijk is van de abstractie, niet van details
class DataManager {
  final DataService _dataService; // Afhankelijkheid van de abstractie

  DataManager(this._dataService); // Dependency injectie (inversie)

  Future<List<String>> fetchData() {
    return _dataService.getData();
  }
}

// Gebruik
void main() {
  final apiService = ApiDataService();
  final localService = LocalDataService();

  final apiManager = DataManager(apiService); // Injectie van ApiDataService
  final localManager = DataManager(localService); // Injectie van LocalDataService

  // ... gebruik van apiManager of localManager
}

In dit voorbeeld hangt DataManager (hoog-niveau module) niet direct af van ApiDataService of LocalDataService. Het hangt af van de abstractie DataService. De concrete implementatie van DataService wordt van buitenaf in DataManager geïnjecteerd, wat een manifestatie is van de dependency inversion. Dit maakt het gemakkelijk om datastromen te wisselen zonder de logica van DataManager te wijzigen.