• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Php - Dependency Injection - czy to to?

Object Storage Arubacloud
0 głosów
356 wizyt
pytanie zadane 20 stycznia 2019 w PHP przez niezalogowany
class A{
    private $zm = 123;
    
    public function getZm(){
        return $this->zm;
    }
}

class B{
    function index(A $a){
        var_dump($a);
    }  
}


$b = new B();
$b->index(new A());

Czy to poprawny sposób wykorzystania wstrzykiwania zalezności? Spotkałem się z stwierdzeniem, że używa się tego aby ograniczyć używanie ooperatora "new" ale jednak aby taki obiekt przekazać trzeba użyć słowa "new", żeby go w ogóle stworzyć.

 

Chodzi mi konkretnie o przykład z laravel'a

class MyController extends Controller
{
    public function index(Request $request){
       var_dump($request->all());
    }
}

Routing:

Route::get('doctors/', 'DoctorController@index');

Laravel sam automatycznie w jakiś sposób dodaje obiekt Request do metody index()?
Dodałem go jedynie jako argument, ale w routingu nie stworzyłem nigdzie nowego obiektu Request i stąd moje pytanie, czy Laravel automatycznie sam z siebie go dodaje widzac, że jest on wymagany w argumentach

1 odpowiedź

0 głosów
odpowiedź 20 stycznia 2019 przez Assasz Nałogowiec (30,460 p.)
wybrane 20 stycznia 2019
 
Najlepsza
Generalnie Dependency Injection pozwala na tworzenie aplikacji, które będą łatwe w testowaniu i rozszerzaniu, ponieważ kiedy będziemy chcieli zmienić daną zależność, to nie powinno być potrzeby modyfikowania kodu, który z tej zależności korzysta (zatem zamiast wskazywać konkretny typ zależności powinniśmy stosować abstrakcję).

Jeśli chodzi o ograniczanie liczby instancji, to do tego raczej służy kontener DI (albo korzystanie z singletonów). Kontener tworzy dokładnie jedną instancję danej klasy i wstrzykuje do niej wszystkie wymagane zależności.

Na temat Laravela się nie wypowiem, bo nie korzystam z tego frameworka :)
komentarz 20 stycznia 2019 przez niezalogowany

no okej czyli do metody w klasie A przekazujemy obiekt typu B i potem na nim wykonujemy już jakieś funkcje np getAddress()
i gdzie tutaj ta łatwość bez potrzeby modyfikowania?

Co jeżeli ktoś stwierdzi, że zmienia obiekt na typ C i klasa C nie posiada wcale metody getAddress(), trzeba pozmieniac albo dorobic metode

 

Jaka jest różnica między

<?php
class A{
    protected $zm = 123;
     
    public function getZm(){
        echo "hello";
    }
}
 
class B{
    function index(A $a){
       $a->getZm();
    }  
}
 
 
$b = new B();
$b->index(new A());

A tym:

<?php
class A{
    protected $zm = 123;
     
    public function getZm(){
        echo "hello";
    }
}
 
class B{
    function index(){
       $a = new A();
       $a->getZm();
    }  
}
 
 
$b = new B();
$b->index();

Oba te kody działają dokładnie tak samo. Dlaczego przekazywanie obiektów jako argumentu metody jest lepsze niż tworzenie obiektu w metodzie lub konstruktorze?
 

komentarz 20 stycznia 2019 przez Assasz Nałogowiec (30,460 p.)

Rozpatrz taki przypadek:

interface ConnectorInterface
{
    public function getConnection(): \PDO;
}

class MySQLConnector implements ConnectorInterface
{
    public function getConnection(): \PDO
    {
        // zwraca połączenie z bazą MySQL
    }
}

class Repository
{
    /**
     * @var \PDO
     */
    private $connection;

    public function __construct(ConnectorInterface $connector)
    {
        $this->connection = $connector->getConnection();
    }
}

Masz dwie klasy, jedna dostarczająca połączenie z bazą MySQL, druga korzystająca z tego połączenia. Co jeśli zechciałbyś nagle zmienić bazę z MySQL na np. PostgreSQL? W tym przypadku wystarczy dostarczyć nową klasę implementującą ConnectorInterface, kod klasy Repository pozostaje bez zmian.

Dlatego też napisałem:

zatem zamiast wskazywać konkretny typ zależności powinniśmy stosować abstrakcję

komentarz 20 stycznia 2019 przez niezalogowany

chyba zrozumiałem!
 

<?php
interface ConnectorInterface
{
    public function getConnection();
}
 
class MySQLConnector implements ConnectorInterface
{
    public function getConnection()
    {
        // zwraca połączenie z bazą MySQL
        echo "MySQL";
    }
}
 
class PostgreSQLConnector implements ConnectorInterface
{
    public function getConnection()
    {
        // zwraca połączenie z bazą MySQL
        echo "PostgreSQL";
    }
}
class Repository
{
    /**
     * @var \PDO
     */
    private $connection;
 
    public function __construct(ConnectorInterface $connector)
    {
        $this->connection = $connector->getConnection();
    }
}


$sql = new PostgreSQLConnector ();
//$sql = new MySQLConnector();
$rep = new Repository($sql);

W tej sytuacji kiedy chcemy zmienić silnik bazy danych wystarczy, że przekażemy inny obiekt. Jednak Mirek miał rację powtarzając cytat:

Doświadczenie pokazuje, iż sukces kursu programowania w znacznej mierze zależy od wyboru prezentowanych przykładów.

Bardzo dziękuję :)

komentarz 20 stycznia 2019 przez Assasz Nałogowiec (30,460 p.)
Proszę bardzo :)
komentarz 20 stycznia 2019 przez niezalogowany

Jeszcze na koniec mój przykład:

<?php
interface VehicleInterface{
    public function getSpeed(): float;
    public function getBrand(): string;
    
    public function setSpeed($speed);
    public function setBrand($brand);
}
 
class Car implements VehicleInterface{
    private $speed;
    private $brand;
    
    public function getSpeed(): float{
        return $this->speed;
    }
    public function getBrand(): string{
        return $this->brand;
    }
    
    public function setSpeed($speed){
        $this->speed = $speed;
        return $this;
    }
    public function setBrand($brand){
        $this->brand = $brand;
        return $this;
    }
}

class Motorcycle implements VehicleInterface{
    private $speed;
    private $brand;
    
    public function getSpeed(): float{
        return ($this->speed*1.1);
    }
    public function getBrand(): string{
        return $this->brand;
    }
    
    public function setSpeed($speed){
        $this->speed = $speed;
        return $this;
    }
    public function setBrand($brand){
        $this->brand = $brand;
        return $this;
    }
}

class Vehicle{
    
    private $type;
    
    public function __construct(VehicleInterface $vi){
        $this->type = $vi;
    }
    
    public function getVehicleInfo(){
        echo $this->type->getSpeed()."\n";
        echo $this->type->getBrand()."\n";
    }
}

$bike = new Motorcycle();
$bike->setSpeed(400);
$bike->setBrand("BMW");

$vehicle = new Vehicle($bike);
$vehicle->getVehicleInfo();


zeby sprawdzić czy na pewno pojąłem to co mi przekazałeś.

komentarz 20 stycznia 2019 przez Assasz Nałogowiec (30,460 p.)
Dokładnie coś takiego.

Podobne pytania

0 głosów
2 odpowiedzi 293 wizyt
pytanie zadane 20 stycznia 2019 w PHP przez niezalogowany
0 głosów
3 odpowiedzi 264 wizyt
pytanie zadane 14 września 2018 w Java przez Pablo93 Użytkownik (800 p.)
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 22 czerwca 2019 w PHP przez niezalogowany

92,624 zapytań

141,482 odpowiedzi

319,822 komentarzy

62,005 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...