Sobes.tech
Middle+

Kokie mechanizmai padeda laikytis priklausomybių inversijos principo?

sobes.tech AI

Atsakymas iš AI

Priklausomybių inversijos principas (Dependency Inversion Principle - DIP) įgyvendinamas keliais tarpusavyje susijusiais mechanizmais:

  1. Abstrakcijos:

    • Sąsajos ir abstraktūs klasės apibrėžia sutartis, o ne konkrečius įgyvendinimus. Aukšto lygio moduliai priklauso nuo šių abstrakcijų, o ne nuo žemyno lygio konkrečių klasių:
  2. Priklausomybių injekcija (Dependency Injection - DI):

    • Vietoj to, kad klasė tiesiog sukurtų savo priklausomybes, jos yra perduodamos iš išorės. Tai leidžia lengvai keisti priklausomybių įgyvendinimus be pačios klasės kodo keitimo:
    • C# sintaksė per konstruktorių injekcijai:
      public class HighLevelModule
      {
          private readonly ILowLevelDependency _dependency; // Abstrakcijos priklausomybė
      
          public HighLevelModule(ILowLevelDependency dependency) // Injekcija per konstruktorių
          {
              _dependency = dependency;
          }
      
          public void PerformAction()
          {
              _dependency.Execute(); // Priklausomybės naudojimas per abstrakciją
          }
      }
      
    • C# sintaksė per savybę:
      public class AnotherHighLevelModule
      {
          public ILowLevelDependency Dependency { get; set; } // Injekcija per savybę
      
          public void PerformAction()
          {
              Dependency?.Execute(); // Priklausomybės naudojimas per abstrakciją
          }
      }
      
    • C# sintaksė per metodą:
      public class YetAnotherHighLevelModule
      {
          public void PerformAction(ILowLevelDependency dependency) // Injekcija per metodą
          {
              dependency.Execute(); // Priklausomybės naudojimas per abstrakciją
          }
      }
      
  3. IoC konteineriai (Inversion of Control Containers):

    • Framework'ai, kurie automatizuoja priklausomybių valdymą ir injekciją. Jie atsakingi už klasių egzempliorių kūrimą ir jų priklausomybių sprendimą pagal nustatytas taisykles:
    • Pavyzdys naudojant populiarų IoC konteinerį (pvz., StructureMap):
      // Priklausomybių registracija
      // container.Configure(cfg =>
      // {
      //     cfg.For<ILowLevelDependency>().Use<ConcreteLowLevelDependency>(); // Abstrakcijos ir jos konkrečios realizacijos registracija
      //     cfg.For<HighLevelModule>().Use<HighLevelModule>();
      // });
      
      // Egzemplioro gavimas su sprendžiamosiomis priklausomybėmis
      // var highLevelModule = container.GetInstance<HighLevelModule>();
      // highLevelModule.PerformAction();
      
  4. Fabrikos:

    • Klasės, kurios atsakingos už kitų klasių egzempliorių kūrimą. Jos gali paslėpti konkrečių realizacijų kūrimo detales ir grąžinti abstrakcijas:
    • C# sintaksė naudojant fabriką:
      public interface ILowLevelDependencyFactory
      {
          ILowLevelDependency Create();
      }
      
      public class LowLevelDependencyFactory : ILowLevelDependencyFactory
      {
          public ILowLevelDependency Create()
          {
              return new ConcreteLowLevelDependency(); // Konkrečios realizacijos kūrimas
          }
      }
      
      public class HighLevelModuleWithFactory
      {
          private readonly ILowLevelDependency _dependency;
      
          public HighLevelModuleWithFactory(ILowLevelDependencyFactory factory) // Fabrikos injekcija
          {
              _dependency = factory.Create(); // Fabrikos naudojimas priklausomybei kurti
          }
      
          public void PerformAction()
          {
              _dependency.Execute();
          }
      }
      
  5. Demer taisyklė (Law of Demeter):

    • Nors tai nėra tiesioginis DIP mechanizmas, šio principo laikymasis (kalbėti tik su savo "draugais") dažnai sumažina tiesiogines priklausomybes ir palengvina DIP taikymą: