среда, 3. септембар 2014.

Labavo vezane komponente u projektu (Dependensy Injection Pattert via PHP)

Prilikom izrade malo zahtevnijih projekata često raste potreba za kreiranjem novih objekata. Međutim, svakako raste potreba za njihovim međusobnim povezivanjima, kako unutar klase, tako i van nje. 
Samo instanciranje objekata, kao i njihovo međusobno povezivanje ne predstavlja problem ali znatno je veći problem što su te veze čvrste. Samim tim je čvrsta i nemogućnost da se aplikacija kasnije nadogradi ili prilagodi nekim novim potrebama. Stoga je neophodno olabaviti zavisnosti.

Pojavom php verzije 5.2 dobijena je mogućnost  prosleđivanja objekata klasama (Dependency Injection Pattern). Dakle, ukoliko je nekoj klasi potreban neki objekat, nesmetano joj se može proslediti. Time je smanjena odgovornost klase da ga sama kreira. 
Dakle Injection == prosleđivanje objekata.

Jedna od mogućnosti prosleđivanja objekata je preko konstruktora klase. Ovo je i najrasprostranjeniji metod, iako se prosleđivanje može vršiti i pomoću setter metoda.

Predstaviću prost primer koji u praksi demonstrira Dependency Injection. Primer se sastoji iz 3 klase, Correct i Fuel sa svojim metodama, kao i Car koju realizuje DI pattern. 

Car.php
<?php
class Car {
    
    //Definisani property klase Car
    private $__correct;
    private $__fuel;
    private $__ignition;

    //Dependency Injection preko konstruktora klase
    public function __construct(Correct $correct, Fuel $fuel) {
        $this->__correct = $correct;
        $this->__fuel = $fuel;
    }
    
    public function go() {
        
        //Automobil moze jedino krenuti ako je ispravan i ako ima goriva
        if ($this->__correct->isCorrect() && $this->__fuel->have_Fuel()) {
            $this->__ignition = TRUE;
        }
        echo 'HERE WE GO!!!!';
    }
    
    public function stop() {
        
        //Ukoliko je automobil neispravan ili nema goriva, ne moze krenuti
        if ($this->__correct->notCorrect() || $this->__fuel->not_Fuel()) {
            $this->__ignition = FALSE;
        }
        echo 'WE HAVE TO STOP!!!';
    }
}

Correct.php
<?php
class Correct {
    
    private $__is_Correct;
    
    public function isCorrect() {
        $this->__is_Correct = TRUE;
    }
    
    public function notCorrect() {
        $this->__is_Correct = FALSE;
    }
    
    public function correct() {
        return $this->__is_Correct;
    }
}

Fuel.php

<?php
class Fuel {
       
    private $__have_Fuel;
    
    public function have_Fuel() {
        
        $this->__have_Fuel = TRUE;
    }
    
    public function not_Fuel() {
        $this->__have_Fuel = FALSE;
    }
    
    public function fuel() {
        return $this->__have_Fuel;
    }
}

Ostaje još index.php koji daje rezultate korišćenjem DI pattern-a. 

<?php
require 'core/init.php'; //Autoloading

$car = new Car(new Correct, new Fuel);

$car->go();
echo "
"; $car->stop();

Kao i ranije, korišćen je autoloading. Iako nema mnogo klasa, zgodno ga je koristiti, naročito ukoliko se javi potreba za preimenovanjem klasa. 

init.php
<?php

spl_autoload_register(function ($class) {
    
    require_once "classes/{$class}.php";
    
});

Ovaj primer, kao i ostale možete videti i na github.com/vlradovanovic
Pozdrav.
Vladimir Radovanović