Middle+
Aké mechanizmy pomáhajú dodržiavať princíp inverzie závislostí?
sobes.tech AI
Odpoveď od AI
Princíp inverzie závislostí (Dependency Inversion Principle - DIP) sa dodržiava pomocou niekoľkých prepojených mechanizmov:
-
Abstrakcie:
- Rozhrania a abstraktné triedy definujú zmluvy, nie konkrétne implementácie. Moduly vysokého stupňa závisia od týchto abstrakcií, nie od nízkoúrovňových konkrétnych tried.
-
**Vstrekovanie závislostí (Dependency Injection - DI):
- Namiesto toho, aby trieda priamo vytvárala svoje závislosti, sú jej odovzdávané zvonku. To umožňuje ľahkú výmenu implementácií závislostí bez zmeny kódu samotnej triedy.
- Syntax C# pre injektovanie cez konštruktor:
public class HighLevelModule { private readonly ILowLevelDependency _dependency; // Závislosť od abstrakcie public HighLevelModule(ILowLevelDependency dependency) // Injektovanie cez konštruktor { _dependency = dependency; } public void PerformAction() { _dependency.Execute(); // Použitie závislosti cez abstrakciu } } - Syntax C# pre injektovanie cez vlastnosť:
public class AnotherHighLevelModule { public ILowLevelDependency Dependency { get; set; } // Injektovanie cez vlastnosť public void PerformAction() { Dependency?.Execute(); // Použitie závislosti cez abstrakciu } } - Syntax C# pre injektovanie cez metódu:
public class YetAnotherHighLevelModule { public void PerformAction(ILowLevelDependency dependency) // Injektovanie cez metódu { dependency.Execute(); // Použitie závislosti cez abstrakciu } }
-
**IoC kontajnery (Inversion of Control Containers):
- Frameworky, ktoré automatizujú proces správy závislostí a ich injektovania. Oni sú zodpovední za vytváranie inštancií tried a riešenie ich závislostí podľa nakonfigurovaných pravidiel.
- Príklad použitia populárneho IoC kontajnera (napríklad StructureMap):
// Registrácia závislosti // container.Configure(cfg => // { // cfg.For<ILowLevelDependency>().Use<ConcreteLowLevelDependency>(); // Registrácia abstrakcie a jej konkrétnej implementácie // cfg.For<HighLevelModule>().Use<HighLevelModule>(); // }); // Získanie inštancie triedy s vyriešenými závislosťami // var highLevelModule = container.GetInstance<HighLevelModule>(); // highLevelModule.PerformAction();
-
Fabriky:
- Triedy, ktoré sú zodpovedné za vytváranie inštancií iných tried. Môžu skrývať detaily vytvárania konkrétnych implementácií a vracať abstrakcie.
- Syntax C# pre príklad použitia fabriky:
public interface ILowLevelDependencyFactory { ILowLevelDependency Create(); } public class LowLevelDependencyFactory : ILowLevelDependencyFactory { public ILowLevelDependency Create() { return new ConcreteLowLevelDependency(); // Vytvorenie konkrétnej implementácie } } public class HighLevelModuleWithFactory { private readonly ILowLevelDependency _dependency; public HighLevelModuleWithFactory(ILowLevelDependencyFactory factory) // Injektovanie fabriky { _dependency = factory.Create(); // Použitie fabriky na vytvorenie závislosti } public void PerformAction() { _dependency.Execute(); } }
-
Zákon najmenších znalostí (Law of Demeter):
- Hoci nie je priamym mechanizmom DIP, dodržiavanie tohto princípu (hovoriť len so svojimi bezprostrednými "priateľmi") často vedie k zníženiu priamej závislosti a uľahčuje aplikáciu DIP.