Sobes.tech
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:

  1. 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.
  2. **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
          }
      }
      
  3. **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();
      
  4. 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();
          }
      }
      
  5. 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.