Middle+
Kādi mehānismi palīdz ievērot atkarību apgriešanas principu?
sobes.tech AI
Atbilde no AI
Atkarības inversijas princips (Dependency Inversion Principle - DIP) tiek īstenots ar vairākām savstarpēji saistītām mehānismiem:
-
Abstrakcijas:
- Interfeisi un abstraktās klases nosaka līgumus, nevis konkrētas realizācijas. Augstākā līmeņa moduļi ir atkarīgi no šīm abstrakcijām, nevis no zemākā līmeņa konkrētām klasēm:
-
Atkarību injekcija (Dependency Injection - DI):
- Tā vietā, lai klase tieši izveidotu savas atkarības, tās tiek nodotas no ārpuses. Tas ļauj viegli aizstāt atkarību realizācijas bez paša klases koda maiņas:
- C# sintakse caur konstruktoru injekciju:
public class HighLevelModule { private readonly ILowLevelDependency _dependency; // Abstrakcijas atkarība public HighLevelModule(ILowLevelDependency dependency) // Injekcija caur konstruktoru { _dependency = dependency; } public void PerformAction() { _dependency.Execute(); // Atkarības izmantošana caur abstrakciju } } - C# sintakse caur īpašību:
public class AnotherHighLevelModule { public ILowLevelDependency Dependency { get; set; } // Injekcija caur īpašību public void PerformAction() { Dependency?.Execute(); // Atkarības izmantošana caur abstrakciju } } - C# sintakse caur metodi:
public class YetAnotherHighLevelModule { public void PerformAction(ILowLevelDependency dependency) // Injekcija caur metodi { dependency.Execute(); // Atkarības izmantošana caur abstrakciju } }
-
IoC konteineri (Inversion of Control Containers):
- Frameworki, kas automatizē atkarību pārvaldību un injekciju. Tie ir atbildīgi par klases instanču izveidi un to atkarību risināšanu saskaņā ar iestatītajiem noteikumiem:
- Piemērs ar populāru IoC konteineru (piemēram, StructureMap):
// Atkarību reģistrācija // container.Configure(cfg => // { // cfg.For<ILowLevelDependency>().Use<ConcreteLowLevelDependency>(); // Abstrakcijas un tās konkrētās realizācijas reģistrācija // cfg.For<HighLevelModule>().Use<HighLevelModule>(); // }); // Klases instanču iegūšana ar risinātajām atkarībām // var highLevelModule = container.GetInstance<HighLevelModule>(); // highLevelModule.PerformAction();
-
Fabrikās:
- Klases, kas atbild par citu klases instanču izveidi. Tās var slēpt konkrētu realizāciju izveides detaļas un atgriezt abstrakcijas:
- C# sintakse ar fabrikas piemēru:
public interface ILowLevelDependencyFactory { ILowLevelDependency Create(); } public class LowLevelDependencyFactory : ILowLevelDependencyFactory { public ILowLevelDependency Create() { return new ConcreteLowLevelDependency(); // Konkrētas realizācijas izveide } } public class HighLevelModuleWithFactory { private readonly ILowLevelDependency _dependency; public HighLevelModuleWithFactory(ILowLevelDependencyFactory factory) // Fabrikas injekcija { _dependency = factory.Create(); // Fabrikas izmantošana atkarības izveidei } public void PerformAction() { _dependency.Execute(); } }
-
Demer likums (Law of Demeter):
- Lai arī tas nav tieši DIP mehānisms, šī principa ievērošana (runāt tikai ar saviem "draugiem") bieži noved pie tiešo atkarību samazināšanas un tādējādi DIP piemērošanas vienkāršošanas: