Middle+
Welche Mechanismen helfen, das Prinzip der Dependency Inversion zu wahren?
sobes.tech KI
Antwort von AI
Das Prinzip der Dependency Inversion (Dependency Inversion Principle - DIP) wird durch mehrere miteinander verbundene Mechanismen eingehalten:
-
Abstraktionen:
- Schnittstellen und abstrakte Klassen definieren Verträge, nicht konkrete Implementierungen. Hochrangige Module hängen von diesen Abstraktionen ab, nicht von konkreten Klassen niedriger Ebene.
-
Dependency Injection (DI):
- Anstatt dass eine Klasse ihre Abhängigkeiten direkt erstellt, werden diese von außen übergeben. Dies ermöglicht es, Implementierungen von Abhängigkeiten leicht zu ersetzen, ohne den Code der Klasse zu ändern.
- C#-Syntax für die Injektion über den Konstruktor:
public class HighLevelModule { private readonly ILowLevelDependency _dependency; // Abhängigkeit von der Abstraktion public HighLevelModule(ILowLevelDependency dependency) // Injektion über den Konstruktor { _dependency = dependency; } public void PerformAction() { _dependency.Execute(); // Verwendung der Abhängigkeit über die Abstraktion } } - C#-Syntax für die Injektion über die Eigenschaft:
public class AnotherHighLevelModule { public ILowLevelDependency Dependency { get; set; } // Injektion über die Eigenschaft public void PerformAction() { Dependency?.Execute(); // Verwendung der Abhängigkeit über die Abstraktion } } - C#-Syntax für die Injektion über die Methode:
public class YetAnotherHighLevelModule { public void PerformAction(ILowLevelDependency dependency) // Injektion über die Methode { dependency.Execute(); // Verwendung der Abhängigkeit über die Abstraktion } }
-
IoC-Container (Inversion of Control Containers):
- Frameworks, die den Prozess der Verwaltung und Injektion von Abhängigkeiten automatisieren. Sie erstellen Instanzen von Klassen und lösen deren Abhängigkeiten gemäß den konfigurierten Regeln.
- Beispiel für die Verwendung eines populären IoC-Containers (z.B. StructureMap):
// Registrierung der Abhängigkeit // container.Configure(cfg => // { // cfg.For<ILowLevelDependency>().Use<ConcreteLowLevelDependency>(); // Registrierung der Abstraktion und ihrer konkreten Implementierung // cfg.For<HighLevelModule>().Use<HighLevelModule>(); // }); // Erhalt einer Instanz der Klasse mit aufgelösten Abhängigkeiten // var highLevelModule = container.GetInstance<HighLevelModule>(); // highLevelModule.PerformAction();
-
Fabriken:
- Klassen, die für die Erstellung von Instanzen anderer Klassen verantwortlich sind. Sie können Details der Erstellung konkreter Implementierungen verbergen und Abstraktionen zurückgeben.
- C#-Syntax für die Verwendung einer Fabrik:
public interface ILowLevelDependencyFactory { ILowLevelDependency Create(); } public class LowLevelDependencyFactory : ILowLevelDependencyFactory { public ILowLevelDependency Create() { return new ConcreteLowLevelDependency(); // Erstellung einer konkreten Implementierung } } public class HighLevelModuleWithFactory { private readonly ILowLevelDependency _dependency; public HighLevelModuleWithFactory(ILowLevelDependencyFactory factory) // Injektion der Fabrik { _dependency = factory.Create(); // Verwendung der Fabrik zur Erstellung der Abhängigkeit } public void PerformAction() { _dependency.Execute(); } }
-
Gesetz der geringsten Kenntnis (Law of Demeter):
- Obwohl kein direkter Mechanismus des DIP, führt die Einhaltung dieses Prinzips (nur mit "nahen Freunden" sprechen) oft zu weniger direkten Abhängigkeiten und erleichtert die Anwendung des DIP.