Lietuvių

Išsamus priklausomybių injekcijos (DI) ir valdymo inversijos (IoC) principų vadovas. Sužinokite, kaip kurti prižiūrimas, testuojamas ir keičiamo dydžio programas.

Priklausomybių injekcija: valdymo inversijos įvaldymas tvirtoms programoms

Programinės įrangos kūrimo srityje tvirtų, prižiūrimų ir keičiamo dydžio programų kūrimas yra svarbiausias dalykas. Priklausomybių injekcija (DI) ir valdymo inversija (IoC) yra esminiai projektavimo principai, kurie suteikia galimybę kūrėjams pasiekti šiuos tikslus. Šis išsamus vadovas nagrinėja DI ir IoC koncepcijas, pateikdamas praktinių pavyzdžių ir naudingų įžvalgų, kurios padės jums įvaldyti šias esmines technikas.

Valdymo inversijos (IoC) supratimas

Valdymo inversija (IoC) yra projektavimo principas, kai programos valdymo srautas yra apverčiamas, palyginti su tradiciniu programavimu. Užuot objektams kuriant ir valdant savo priklausomybes, ši atsakomybė perduodama išoriniam subjektui, paprastai IoC konteineriui ar sistemai. Ši valdymo inversija suteikia keletą privalumų, įskaitant:

Tradicinis valdymo srautas

Tradiciniame programavime klasė paprastai tiesiogiai sukuria savo priklausomybes. Pavyzdžiui:


class ProductService {
  private $database;

  public function __construct() {
    $this->database = new DatabaseConnection("localhost", "username", "password");
  }

  public function getProduct(int $id) {
    return $this->database->query("SELECT * FROM products WHERE id = " . $id);
  }
}

Šis požiūris sukuria glaudų susiejimą tarp ProductService ir DatabaseConnection. Klasė ProductService yra atsakinga už DatabaseConnection kūrimą ir valdymą, todėl ją sunku testuoti ir pakartotinai naudoti.

Apverstas valdymo srautas su IoC

Naudojant IoC, ProductService gauna DatabaseConnection kaip priklausomybę:


class ProductService {
  private $database;

  public function __construct(DatabaseConnection $database) {
    $this->database = $database;
  }

  public function getProduct(int $id) {
    return $this->database->query("SELECT * FROM products WHERE id = " . $id);
  }
}

Dabar ProductService pati nekuria DatabaseConnection. Ji pasikliauja išoriniu subjektu, kuris pateikia priklausomybę. Ši valdymo inversija padaro ProductService lankstesne ir lengviau testuojama.

Priklausomybių injekcija (DI): IoC įgyvendinimas

Priklausomybių injekcija (DI) yra projektavimo šablonas, kuris įgyvendina valdymo inversijos principą. Jis apima objekto priklausomybių pateikimą objektui, užuot objektui pačiam jas kuriant ar ieškant. Yra trys pagrindiniai priklausomybių injekcijos tipai:

Konstruktoriaus injekcija

Konstruktoriaus injekcija yra labiausiai paplitęs ir rekomenduojamas DI tipas. Ji užtikrina, kad objektas gauna visas reikiamas priklausomybes kūrimo metu.


class UserService {
  private $userRepository;

  public function __construct(UserRepository $userRepository) {
    $this->userRepository = $userRepository;
  }

  public function getUser(int $id) {
    return $this->userRepository->find($id);
  }
}

// Pavyzdinis naudojimas:
$userRepository = new UserRepository(new DatabaseConnection());
$userService = new UserService($userRepository);
$user = $userService->getUser(123);

Šiame pavyzdyje UserService gauna UserRepository egzempliorių per savo konstruktorių. Tai leidžia lengvai testuoti UserService pateikiant imitacinę UserRepository.

Nustatymo metodo (Setter) injekcija

Nustatymo metodo injekcija leidžia priklausomybes įšvirkšti po to, kai objektas jau buvo sukurtas.


class OrderService {
  private $paymentGateway;

  public function setPaymentGateway(PaymentGateway $paymentGateway) {
    $this->paymentGateway = $paymentGateway;
  }

  public function processOrder(Order $order) {
    $this->paymentGateway->processPayment($order->getTotal());
    // ...
  }
}

// Pavyzdinis naudojimas:
$orderService = new OrderService();
$orderService->setPaymentGateway(new PayPalGateway());
$orderService->processOrder($order);

Nustatymo metodo injekcija gali būti naudinga, kai priklausomybė yra neprivaloma arba gali būti pakeista vykdymo metu. Tačiau tai taip pat gali padaryti objekto priklausomybes mažiau aiškias.

Sąsajos injekcija

Sąsajos injekcija apima sąsajos apibrėžimą, kuri nurodo priklausomybės injekcijos metodą.


interface Injectable {
  public function setDependency(Dependency $dependency);
}

class ReportGenerator implements Injectable {
  private $dataSource;

  public function setDependency(Dependency $dataSource) {
    $this->dataSource = $dataSource;
  }

  public function generateReport() {
    // Naudoti $this->dataSource ataskaitai generuoti
  }
}

// Pavyzdinis naudojimas:
$reportGenerator = new ReportGenerator();
$reportGenerator->setDependency(new MySQLDataSource());
$reportGenerator->generateReport();

Sąsajos injekcija gali būti naudinga, kai norite priverstinai laikytis konkrečios priklausomybių injekcijos sutarties. Tačiau tai taip pat gali pridėti kodo sudėtingumo.

IoC konteineriai: Priklausomybių injekcijos automatizavimas

Rankinis priklausomybių valdymas gali tapti varginantis ir linkęs į klaidas, ypač didelėse programose. IoC konteineriai (taip pat žinomi kaip priklausomybių injekcijos konteineriai) yra sistemos, kurios automatizuoja priklausomybių kūrimo ir įšvirkštimo procesą. Jie suteikia centralizuotą vietą priklausomybių konfigūravimui ir jų išsprendimui vykdymo metu.

IoC konteinerių naudojimo privalumai

Populiarūs IoC konteineriai

Daugybė IoC konteinerių yra prieinami įvairioms programavimo kalboms. Kai kurie populiarūs pavyzdžiai:

Pavyzdys naudojant Laravel IoC konteinerį (PHP)


// Susieti sąsają su konkrečia implementacija
use App\Interfaces\PaymentGatewayInterface;
use App\Services\PayPalGateway;

$this->app->bind(PaymentGatewayInterface::class, PayPalGateway::class);

// Išspręsti priklausomybę
use App\Http\Controllers\OrderController;

public function store(Request $request, PaymentGatewayInterface $paymentGateway) {
    // $paymentGateway yra automatiškai įšvirkščiamas
    $order = new Order($request->all());
    $paymentGateway->processPayment($order->total);
    // ...
}

Šiame pavyzdyje Laravel IoC konteineris automatiškai išsprendžia PaymentGatewayInterface priklausomybę OrderController ir įšvirkščia PayPalGateway egzempliorių.

Priklausomybių injekcijos ir valdymo inversijos privalumai

DI ir IoC pritaikymas siūlo daugybę privalumų programinės įrangos kūrimui:

Padidintas testuojamumas

DI žymiai palengvina vienetų testų rašymą. Įšvirkšdami imitacines ar fiktyvias priklausomybes, galite izoliuoti testuojamą komponentą ir patikrinti jo elgseną, nepasikliaudami išorinėmis sistemomis ar duomenų bazėmis. Tai yra labai svarbu norint užtikrinti kodo kokybę ir patikimumą.

Sumažintas susiejimas

Laisvas susiejimas yra pagrindinis gero programinės įrangos projektavimo principas. DI skatina laisvą susiejimą, mažindama priklausomybes tarp objektų. Tai daro kodą moduliškesnį, lankstesnį ir lengviau prižiūrimą. Vieno komponento pakeitimai mažiau tikėtina, kad paveiks kitas programos dalis.

Pagerintas prižiūrimumas

Programos, sukurtos naudojant DI, paprastai yra lengviau prižiūrimos ir modifikuojamos. Modulinis dizainas ir laisvas susiejimas palengvina kodo supratimą ir pakeitimų atlikimą neįvedant nenumatytų šalutinių poveikių. Tai ypač svarbu ilgalaikiams projektams, kurie vystosi laikui bėgant.

Pagerintas pakartotinis panaudojamumas

DI skatina kodo pakartotinį panaudojimą, darant komponentus labiau nepriklausomus ir autonomiškus. Komponentus galima lengvai pakartotinai naudoti skirtinguose kontekstuose su skirtingomis priklausomybėmis, sumažinant kodo dubliavimo poreikį ir gerinant bendrą kūrimo proceso efektyvumą.

Padidintas moduliškumas

DI skatina modulinį dizainą, kai programa yra padalinta į mažesnius, nepriklausomus komponentus. Tai palengvina kodo supratimą, testavimą ir modifikavimą. Tai taip pat leidžia skirtingoms komandoms vienu metu dirbti su skirtingomis programos dalimis.

Supaprastinta konfigūracija

IoC konteineriai suteikia centralizuotą vietą priklausomybių konfigūravimui, todėl lengviau valdyti ir prižiūrėti programą. Tai sumažina rankinio konfigūravimo poreikį ir pagerina bendrą programos nuoseklumą.

Geriausios priklausomybių injekcijos praktikos

Norėdami efektyviai naudoti DI ir IoC, apsvarstykite šias geriausias praktikas:

Dažniausi antišablonai

Nors priklausomybių injekcija yra galingas įrankis, svarbu vengti dažniausių antišablonų, kurie gali pakenkti jos privalumams:

Priklausomybių injekcija skirtingose programavimo kalbose ir sistemose

DI ir IoC yra plačiai palaikomi įvairiose programavimo kalbose ir sistemose. Štai keletas pavyzdžių:

Java

Java kūrėjai priklausomybių injekcijai dažnai naudoja tokias sistemas kaip Spring Framework ar Guice.


@Component
public class ProductServiceImpl implements ProductService {

    private final ProductRepository productRepository;

    @Autowired
    public ProductServiceImpl(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    // ...
}

C#

.NET teikia integruotą priklausomybių injekcijos palaikymą. Galite naudoti Microsoft.Extensions.DependencyInjection paketą.


public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient();
        services.AddTransient();
    }
}

Python

Python siūlo bibliotekas, tokias kaip injector ir dependency_injector, skirtas DI įgyvendinimui.


from dependency_injector import containers, providers

class Container(containers.DeclarativeContainer):
    database = providers.Singleton(Database, db_url="localhost")
    user_repository = providers.Factory(UserRepository, database=database)
    user_service = providers.Factory(UserService, user_repository=user_repository)

container = Container()
user_service = container.user_service()

JavaScript/TypeScript

Sistemos, tokios kaip Angular ir NestJS, turi integruotas priklausomybių injekcijos galimybes.


import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class ProductService {
  constructor(private http: HttpClient) {}

  // ...
}

Realūs pavyzdžiai ir naudojimo atvejai

Priklausomybių injekcija taikoma įvairiausiuose scenarijuose. Štai keletas realių pavyzdžių:

Išvada

Priklausomybių injekcija ir valdymo inversija yra fundamentalūs projektavimo principai, kurie skatina laisvą susiejimą, gerina testuojamumą ir didina programinės įrangos prižiūrimumą. Įvaldę šias technikas ir efektyviai naudodami IoC konteinerius, kūrėjai gali sukurti tvirtesnes, keičiamo dydžio ir lengviau pritaikomas sistemas. DI/IoC pritaikymas yra esminis žingsnis link aukštos kokybės programinės įrangos, atitinkančios šiuolaikinės kūrimo reikalavimus, kūrimo.