Sobes.tech
Middle

Was kannst du über das Prinzip D in SOLID erzählen?

sobes.tech KI

Antwort von AI

Das Prinzip der Dependency Inversion (Dependency Inversion Principle) besagt:

  • Module höherer Ebenen sollten nicht von Modulen niedriger Ebenen abhängen. Beide Modularten sollten von Abstraktionen abhängen.
  • Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.

Das Ziel des D in SOLID ist es, die Kopplung (decoupling) von hochrangigen Richtlinien von der Implementierung auf niedriger Ebene zu lösen. Anstatt dass ein hochrangiges Modul direkt von der konkreten Implementierung eines Moduls auf niedriger Ebene abhängt, hängen beide von einer gemeinsamen Schnittstelle oder einer abstrakten Klasse ab. Dies erhöht die Flexibilität, Testbarkeit und Wartbarkeit des Codes.

In Flutter zeigt sich dies oft durch die Verwendung abstrakter Klassen oder Mixins zur Definition von Verträgen, die dann von konkreten Klassen implementiert werden. Zum Beispiel bei der Arbeit mit Daten:

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

// Niedrigstufige Implementierung (konkretes Detail)
class ApiDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logik zum Abrufen von Daten aus einer API
    return ['API Data 1', 'API Data 2'];
  }
}

// Andere niedrigstufige Implementierung (anderes konkretes Detail)
class LocalDataService implements DataService {
  @override
  Future<List<String>> getData() async {
    // Logik zum Abrufen von Daten aus lokalem Speicher
    return ['Local Data 1', 'Local Data 2'];
  }
}

// Hochrangiges Modul, das von der Abstraktion abhängt, nicht von Details
class DataManager {
  final DataService _dataService; // Abhängigkeit von der Abstraktion

  DataManager(this._dataService); // Abhängigkeit wird injiziert (Inversion)

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

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

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

  // ... Verwendung von apiManager oder localManager
}

In diesem Beispiel hängt DataManager (das hochrangige Modul) nicht direkt von ApiDataService oder LocalDataService ab. Es hängt von der Abstraktion DataService ab. Die konkrete Implementierung von DataService wird von außen in DataManager "injiziert", was eine Manifestation der Dependency Inversion ist. Dies ermöglicht es, Datenquellen leicht zu wechseln, ohne die Logik von DataManager zu ändern.