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

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