Sobes.tech
Middle

Ce poți să-mi spui despre principiul D în SOLID?

sobes.tech AI

Răspuns de la AI

Principiul inversiunii dependențelor (Dependency Inversion Principle) afirmă:

  • Modulele de nivel superior nu trebuie să depindă de modulele de nivel inferior. Ambele tipuri de module trebuie să depindă de abstracții.
  • Abstracțiile nu trebuie să depindă de detalii. Detaliile trebuie să depindă de abstracții.

Scopul D în SOLID este de a decupla (decoupling) politicile de nivel înalt de implementarea de nivel inferior. În loc ca un modul de nivel înalt să depindă direct de implementarea concretă a unui modul de nivel inferior, ambele depind de o interfață comună sau de o clasă abstractă. Acest lucru crește flexibilitatea, testabilitatea și întreținerea codului.

În Flutter, acest lucru se manifestă adesea prin utilizarea de clase abstracte sau mixin-uri pentru definirea contractelor, care sunt apoi implementate de clase concrete. De exemplu, când se lucrează cu date:

// Abstracție
abstract class DataService {
  Future<List<String>> getData();
}

// Implementare de nivel inferior (detaliu concret)
class ApiDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logica de obținere a datelor din API
    return ['API Data 1', 'API Data 2'];
  }
}

// Altă implementare de nivel inferior (alt detaliu concret)
class LocalDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logica de obținere a datelor din stocarea locală
    return ['Local Data 1', 'Local Data 2'];
  }
}

// Modul de nivel înalt, care depinde de abstracție, nu de detalii
class DataManager {
  final DataService _dataService; // Dependență de abstracție

  DataManager(this._dataService); // Inversiunea dependenței

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

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

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

  // ... utilizare apiManager sau localManager
}

În acest exemplu, DataManager (modul de nivel înalt) nu depinde direct de ApiDataService sau LocalDataService. El depinde de abstracția DataService. Implementarea concretă a DataService este "injectată" în DataManager din exterior, ceea ce reprezintă o manifestare a inversiunii dependenței. Acest lucru permite schimbarea ușoară a surselor de date fără a modifica logica DataManager.