Middle+
Jaké mechanismy pomáhají dodržovat princip inverze závislostí?
sobes.tech AI
Odpověď od AI
Princip inverze závislostí (Dependency Inversion Principle - DIP) je dodržován pomocí několika vzájemně propojených mechanismů:
-
Abstrakce:
- Rozhraní a abstraktní třídy definují smlouvy, nikoli konkrétní implementace. Vyšší moduly závisí na těchto abstrakcích, nikoli na nízkoúrovňových konkrétních třídách.
-
**Vstřikování závislostí (Dependency Injection - DI):
- Místo toho, aby třída přímo vytvářela své závislosti, jsou jí předávány zvenčí. To umožňuje snadnou výměnu implementací závislostí bez změny kódu třídy.
- Syntaxe C# pro injektování přes konstruktor:
public class HighLevelModule { private readonly ILowLevelDependency _dependency; // Závislost na abstrakci public HighLevelModule(ILowLevelDependency dependency) // Injektování přes konstruktor { _dependency = dependency; } public void PerformAction() { _dependency.Execute(); // Použití závislosti přes abstrakci } } - Syntaxe C# pro injektování přes vlastnost:
public class AnotherHighLevelModule { public ILowLevelDependency Dependency { get; set; } // Injektování přes vlastnost public void PerformAction() { Dependency?.Execute(); // Použití závislosti přes abstrakci } } - Syntaxe C# pro injektování přes metodu:
public class YetAnotherHighLevelModule { public void PerformAction(ILowLevelDependency dependency) // Injektování přes metodu { dependency.Execute(); // Použití závislosti přes abstrakci } }
-
**IoC kontejnery (Inversion of Control Containers):
- Frameworky, které automatizují správu závislostí a jejich injektování. Zodpovídají za vytváření instancí tříd a řešení jejich závislostí podle nastavených pravidel.
- Příklad použití populárního IoC kontejneru (například StructureMap):
// Registrace závislosti // container.Configure(cfg => // { // cfg.For<ILowLevelDependency>().Use<ConcreteLowLevelDependency>(); // Registrace abstrakce a její konkrétní implementace // cfg.For<HighLevelModule>().Use<HighLevelModule>(); // }); // Získání instance třídy s vyřešenými závislostmi // var highLevelModule = container.GetInstance<HighLevelModule>(); // highLevelModule.PerformAction();
-
Fabriky:
- Třídy, které jsou zodpovědné za vytváření instancí jiných tříd. Mohou skrývat detaily vytváření konkrétních implementací a vracet abstrakce.
- Syntaxe C# pro použití fabriky jako příklad:
public interface ILowLevelDependencyFactory { ILowLevelDependency Create(); } public class LowLevelDependencyFactory : ILowLevelDependencyFactory { public ILowLevelDependency Create() { return new ConcreteLowLevelDependency(); // Vytvoření konkrétní implementace } } public class HighLevelModuleWithFactory { private readonly ILowLevelDependency _dependency; public HighLevelModuleWithFactory(ILowLevelDependencyFactory factory) // Injektování fabriky { _dependency = factory.Create(); // Použití fabriky k vytvoření závislosti } public void PerformAction() { _dependency.Execute(); } }
-
Zákon minimálních znalostí (Law of Demeter):
- Ačkoli není přímým mechanismem DIP, dodržování tohoto principu (mluvit pouze se svými přímými "přáteli") často vede ke snížení přímých závislostí a usnadňuje aplikaci DIP.