Sobes.tech
Middle

Co możesz powiedzieć o zasadzie D w SOLID?

sobes.tech AI

Odpowiedź od AI

Zasada odwracania zależności (Dependency Inversion Principle) mówi:

  • Moduły wyższego poziomu nie powinny zależeć od modułów niższego poziomu. Oba typy modułów powinny zależeć od abstrakcji.
  • Abstrakcje nie powinny zależeć od szczegółów. Szczegóły powinny zależeć od abstrakcji.

Cel D w SOLID — odłączenie (decoupling) polityk wysokiego poziomu od implementacji niskiego poziomu. Zamiast, aby moduł wysokiego poziomu bezpośrednio zależał od konkretnej implementacji modułu niskiego poziomu, oba zależą od wspólnego interfejsu lub klasy abstrakcyjnej. To zwiększa elastyczność, testowalność i utrzymanie kodu.

W Flutter często objawia się to przez użycie klas abstrakcyjnych lub mixinów do definiowania kontraktów, które następnie są implementowane przez konkretne klasy. Na przykład, przy pracy z danymi:

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

// Niskopoziomowa implementacja (konkretny szczegół)
class ApiDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logika pobierania danych z API
    return ['API Data 1', 'API Data 2'];
  }
}

// Inna niskopoziomowa implementacja (inny szczegół)
class LocalDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logika pobierania danych z lokalnego magazynu
    return ['Local Data 1', 'Local Data 2'];
  }
}

// Moduł wysokiego poziomu zależy od abstrakcji, nie od szczegółów
class DataManager {
  final DataService _dataService; // Zależność od abstrakcji

  DataManager(this._dataService); // Wstrzykiwanie zależności (inwersja)

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

// Użycie
void main() {
  final apiService = ApiDataService();
  final localService = LocalDataService();

  final apiManager = DataManager(apiService); // Wstrzyknięcie ApiDataService
  final localManager = DataManager(localService); // Wstrzyknięcie LocalDataService

  // ... użycie apiManager lub localManager
}

W tym przykładzie DataManager (moduł wysokiego poziomu) nie zależy bezpośrednio od ApiDataService czy LocalDataService. Zależy od abstrakcji DataService. Konkretną implementację DataService "wstrzykuje" się do DataManager z zewnątrz, co jest przejawem odwrócenia zależności. Umożliwia to łatwą wymianę źródeł danych bez zmiany logiki DataManager.