Poslao: 10 Dec 2014 20:46
|
offline
- E.L.I.T.E.
- Legendarni građanin
- Pridružio: 23 Maj 2012
- Poruke: 4575
|
Nije mi baš jasan ovaj koncept. Naprimer imam dve klase (Author i Question):
<?php
class Author {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->lastName;
}
}
class Question {
private $author;
private $question;
public function __construct($question, $authorFirstName, $authorLastName) {
$this->author = new Author($authorFirstName, $authorLastName);
$this->question = $question;
}
public function getAuthor() {
return $this->author;
}
public function getQuestion() {
return $this->question;
}
}
?>
U ovom prvom kodu je jasno da objekat Author nema šta da traži u klasi Question. Sad taj isti kod sa odrađenim dependency injection:
<?php
class Author {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFirstName() {
return $this->firstName;
}
public function getLastName() {
return $this->lastName;
}
}
class Question {
private $author;
private $question;
public function __construct($question, Author $author) {
$this->author = $author;
$this->question = $question;
}
public function getAuthor() {
return $this->author;
}
public function getQuestion() {
return $this->question;
}
}
?>
Šta sad tačno radi ovo Author (pretpostavljam da predstavlja neku spregu između klase Question i Author) u konstruktoru unutar klase Question?
Imam još jedno pitanje, kada i zbog čega treba da koristim dependency injection tj. koja je korist od njegovog korišćenja?
|
|
|
Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
|
|
|
Poslao: 11 Dec 2014 11:22
|
offline
- E.L.I.T.E.
- Legendarni građanin
- Pridružio: 23 Maj 2012
- Poruke: 4575
|
Gledam neke video tutorijale sa phpAcademy vezane za OOP pa sam naleteo i na DI... ništa, onda ću ga preskočiti za sad, možda kroz dalje učenje uspem da pohvatam više stvari oko toga
|
|
|
|
Poslao: 12 Dec 2014 19:17
|
offline
- Pridružio: 16 Feb 2011
- Poruke: 1630
- Gde živiš: Pancevo
|
Di je jako mocna stvar pogotovo ces videti ako budes radio Symfony Framework pa kada budes radio svoje servise i najvise gde on koristi DI je za rad sa formam-a i Doctrine. Jako mocna stvar ali teska za skontati kad je nabolje iskoristiti.
|
|
|
|
Poslao: 12 Dec 2014 19:27
|
offline
- igorpan
- Super građanin
- Pridružio: 10 Avg 2006
- Poruke: 1009
- Gde živiš: Beograd
|
Nije ništa komplikovano, koncept je jako jednostavan. A senior koji se muči sa dependency injectionom nije senior.
Loš si primer sebi izabrao jer su ove dve klase koje ti imaš Data Objekti, čija je primarna svrha da čuvaju neke podatke a ne da imaju funkcionalnost neku.
DependencyInjection ti je šablon po kome instance klase "dobijaju" ono što im je neophodno za rad. Primera radi, imaš klasu čiji objekti imaju svrhu da čuvaju podatke. Ali ti iz nekog razloga želiš da možeš da biraš gde se čuvaju: u fajl na sistemu ili u MySql bazu na primer. DependencyInjectionom možeš ovo
na prilično elegantan način da rešiš:
<?php
class DataSaver
{
private $storageAdapter;
public function __construct($storageAdapter)
{
$this->storageAdapter = $storageAdapter;
}
public function saveData($data)
{
str_replace('a', 'b', $data); // Obradiš podatke kako želiš...
$this->storageAdapter->save($data);
}
}
class FileStorageAdapter
{
public function save($data)
{
file_put_contents('lokacija/do/fajla', $data);
}
}
class MySqlStorageAdapter
{
public function save($data)
{
mysqli_query('INSERT INTO blahblah.......');
}
}
// Sada kada imaš ova dva adaptera ti možeš istu klasu da iskoristiš da čuvaš fajlove i na filesystemu i u bazi:
$fileSystemSaver = new DataSaver(new FileStorageAdapter());
$mysqlSaver = new DataSaver(new MySqlStorageAdapter());
$data = 'neki podaci';
$filesystemSaver->saveData($data); // Obradi i sačuva na filesystem
$mysqlSaver->saveData($data); // Obradi i sačuva u MySQL bazu
U ovakvom primeru bi trebalo da ti dosta jasnije bude šta je to Dependency Injection zapravo. Koristimo ga za DataSaver klasu. DataSaver nema pojma koji će adapter da dobije i ne zanima ga. Zanima ga da on ima isti javni interfejs (u ovom slučaju "save" metod, naučićeš kasnije o interfejsima u PHPu konkretno).
Ovo je što sam naveo jako jednostavan primer, mi ovde "ručno" ubacujemo adaptere i pravimo instance DataSaver klase. Kasnije ćeš naučiti kako se to može izvesti na druge načine pomoću "Containera" i "Service Providera", ali princip Dependency Injectiona je to: "Ja znam šta mi treba, ali neću ja da konstruišem to nego ćeš mi ti to dati". Ovaj šablon ima mnoge prednosti, jedna od njih je lako testiranje koda.
|
|
|
|
|
Poslao: 12 Dec 2014 21:08
|
offline
- igorpan
- Super građanin
- Pridružio: 10 Avg 2006
- Poruke: 1009
- Gde živiš: Beograd
|
To je bio samo primer, možda ne najsrećniji ali da. Poenta je bila da shvatiš šta je Dependency Injection. To je "ubrizgavanje" ovih adaptera u DataSaver kroz njegov constructor.
|
|
|
|
Poslao: 14 Dec 2014 16:47
|
offline
- Pridružio: 25 Jan 2004
- Poruke: 2784
- Gde živiš: Niš
|
Obično je sve teže objasniti kad se objašnjava 'ŠTA' je u pitanju nego 'ZAŠTO'.
@igorpan i _iKaC su ti super objasnili šta je DI, mada ti je Igor na kraju i napisao benefite ove paterne koji bi trebalo da ti kažu zašto.
Kao i svaki pristup rešavanju nekog problema, i ovaj mora da je proistekao iz neke potrebe.
Ako bi imao sistem u kome komponente previše znaju jedna o drugoj, nemoguće ih je jednostavno razdvojiti, zameniti nekim drugim komponentama ili tretirati kao 'male programe' i zasebno testirati (unit testing). Sistem takođe plače za teško rešivim bagovima ako objekti direktno menjaju elemente drugih objekta jer je onda teško uloviti 'ko tu šta radi' a u nekim slučajevima to bude i najveći deo vremena provedenog na nekom projektu, pa je skoro uvek dobro razdvojiti komponente i u svakom od tih komponenti/objekta napraviti interfejse komunikacije (ne dozvoliti da drugi objekti direktno manipulišu internom strukturom tog objekta).
Ovo poslednje i nije deo Dependancy Injection paterne ali je poprilično komplementarno i naravno - savet iz ličnog iskustva. Ne mogu da ti opišem noćne more 'održavanja' koda u kome se nije znalo ko koga zove a ko drnda prekidače.
http://en.wikipedia.org/wiki/Law_of_Demeter
|
|
|
|
|
Poslao: 15 Dec 2014 16:56
|
offline
- Pridružio: 16 Feb 2011
- Poruke: 1630
- Gde živiš: Pancevo
|
Eto jedan jako ali jako dobar primer primer Symfony komponenti. Svaku komponentu mozes koristiti bez prisustva Symfony Core. Znaci nezavisna je i moze se koristiti u svakom vasem projektu. DI je uradio svoje
|
|
|
|