Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Laravel i code incjection w konstruktorze - po co?
konrados
post 11.06.2015, 17:18:29
Post #1





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


Cześć.

Analizuję framework Laravel, i kolejna rzecz nie daje mi spokoju.

Tworząc klasę kontrolera zauważyłem, że większość ludzi pobiera jako jego parametry instancje różnych klas potrzebnych do dalszego działania.

Czyli mamy np. coś takiego:

  1. class AdminController extends Controller {
  2.  
  3.  
  4. protected $someObject;
  5.  
  6. /**
  7.   * Create a new AdminController instance.
  8.   *
  9.   * @return void
  10.   */
  11. public function __construct(SomeClass $someObject)
  12. {
  13. $this->someObject = $someObject;
  14. }
  15. (...)


I tu mam pytanie - po co to? W jaki sposób to ulepsza nasz kod? Czy nie lepiej napisać:
  1. public function __construct()
  2. {
  3. $this->someObject = new someClass();
  4. }

?

Jest bardziej znajome, nie trzeba się uczyć nowej składni. Czy może są jakieś zalety, których nie dostrzegam?

Ten post edytował konrados 11.06.2015, 17:23:19
Go to the top of the page
+Quote Post
Pyton_000
post 11.06.2015, 17:29:19
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


No to tak:
1. Nie uzależniasz obiektu kasy od innych klas. Wiąże się to z SOLID
2. Testowanie. Możesz testować klasę. Jako parametr wtedy przekazujesz Moc, Stub czy inne cuda.
3. Nikt nie każe używać tego, jednak możesz przekazać Interfejs jako Typ a w samym Laravel zdefiniować implementację której używasz. Dzięki temu zmieniasz implementację w jednym miejscu a nie we wszystkich klasach które używają go.
4. Dzięki temu możesz zainicjować np. obiekt który stanie się Singletonem defacto nie będąc nim. Np. Klasa Repozytorium która przechowuje metody pobierające jakieś dane. Nie musisz tworzyć z niej defacto singletona. Wystarczy że zdefiniujesz jej zachowanie w 1 linijce w jakimś ServiceProvider i już mamy singleton. A jak nam się odwidzi to usuwamy model zachowania i już mamy zwykłe zachowanie.

To tak na szybko co mi wpadło do głowy smile.gif
Go to the top of the page
+Quote Post
konrados
post 11.06.2015, 18:33:06
Post #3





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


Dzięki, wiedziałem, że jak chodzi o Laravel, to Ty odpowiesz:)

Punktu pierwszego z początku nie rozumiałem, zrozumiałem jak przeczytałem punkt 3 z parametrem typu interfejs i potem przekazywaniem innej klasy dziedziczącej z tego interfejsu. Ale, a propos tego punktu 3 - czy dobrze rozumiem, że chodzi o to, że może być wiele takich kontrolerów i możemy jedną linijką zmienić klasę, która jest przekazywana? Ale jak tak, to mam inne pytanie.

Powiedzmy, że chodzi o klasę User, która reprezentuje aktualnie zalogowanego usera. Prawie każdy kontroler tego potrzebuje. I przy tym podejściu, każdy kontroler w konstruktorze musi jako parametr pobierać klasę tego usera. Strasznie dużo pisania, szczególnie, że takich przekazywanych klas może być bardzo dużo. Piszę własny mini-framework, i tam (na razie) poszedłem w innym kierunku: klasa User jest zdefiniowana w "rdzeniu" frameworka, ma takie methody jak login czy logout. Natomiast jest specjalny katalog w katalogu "application" w którym istnieje druga klasa "User", która dziedziczy z frameworkowej klasy User. Z założenia tę klasę user może modyfikować (w przeciwieństwie do tej wersji frameworkowej) i w całej aplikacji ma właśnie używać tej klasy.

Podobnie jest z każdą inną klasą frameworkową - Html, Input, Form etc. Każdą developer może nadpisać.

I teraz, pomijając Twój punkt 2 (dotyczący testowania) - czy moje rozwiązanie nie wydaje się lepsze a przynajmniej prostsze?
Go to the top of the page
+Quote Post
Pyton_000
post 11.06.2015, 18:53:39
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Dzięki wink.gif
Co do...

Cytat(konrados @ 11.06.2015, 19:33:06 ) *
Punktu pierwszego z początku nie rozumiałem, zrozumiałem jak przeczytałem punkt 3 z parametrem typu interfejs i potem przekazywaniem innej klasy dziedziczącej z tego interfejsu. Ale, a propos tego punktu 3 - czy dobrze rozumiem, że chodzi o to, że może być wiele takich kontrolerów i możemy jedną linijką zmienić klasę, która jest przekazywana? Ale jak tak, to mam inne pytanie.


Tak. Do kontrolera (w Laravel 5 także do metody) możesz przekazać Interfejs. Potem w "bootstrap/app.php" definiujesz jaka klasa ma być Wstrzyknięta.

Cytat(konrados @ 11.06.2015, 19:33:06 ) *
Powiedzmy, że chodzi o klasę User, która reprezentuje aktualnie zalogowanego usera. Prawie każdy kontroler tego potrzebuje. I przy tym podejściu, każdy kontroler w konstruktorze musi jako parametr pobierać klasę tego usera. Strasznie dużo pisania, szczególnie, że takich przekazywanych klas może być bardzo dużo. Piszę własny mini-framework, i tam (na razie) poszedłem w innym kierunku: klasa User jest zdefiniowana w "rdzeniu" frameworka, ma takie methody jak login czy logout. Natomiast jest specjalny katalog w katalogu "application" w którym istnieje druga klasa "User", która dziedziczy z frameworkowej klasy User. Z założenia tę klasę user może modyfikować (w przeciwieństwie do tej wersji frameworkowej) i w całej aplikacji ma właśnie używać tej klasy.

Nie wiem o co chodzi smile.gif Ale jeśli chodzi o zalogowanego usera to możesz się dobrać do niego przez:

  1. autch()->user()

To jest helper.

Możesz zawsze nadpisać klasę Users tak jak pisałeś i wtedy w ww. pliku zdefiniować że każde odwołanie do Users z L5 to ma być Twoje Users

Nie wiem czy dobrze zrozumiałem to co napisałeś smile.gif
Go to the top of the page
+Quote Post
konrados
post 11.06.2015, 19:42:43
Post #5





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


Cytat
Nie wiem czy dobrze zrozumiałem to co napisałeś


Chodzi właśnie mi o to:

Cytat
Tak. Do kontrolera (w Laravel 5 także do metody) możesz przekazać Interfejs. Potem w "bootstrap/app.php" definiujesz jaka klasa ma być Wstrzyknięta.


To jest koncepcja z Laravela i ja ją teraz rozumiem.

Moja natomiast jest chyba podobna ale inna. Definiujemy klasę "User" w naszej aplikacji, która dziedziczy po klasie "User" we frameworku. I... nic więcej nie trzeba robić. Nie trzeba edytować żadnego pliku typu "bootstrap/app.php" - dlatego, że mój framework sam będzie wiedział, że ma skorzystać z tej klasy napisanej przez developera w katalogu aplikacji.

I właśnie się zastanawiam, czy to nie jest błąd. Bo niby prostsze w użyciu, ale potem może się okazać, że jednak metoda a'la Laravel jest z jakiegoś powodu lepsza...
Go to the top of the page
+Quote Post
by_ikar
post 11.06.2015, 19:52:36
Post #6





Grupa: Zarejestrowani
Postów: 1 798
Pomógł: 307
Dołączył: 13.05.2009
Skąd: Gubin/Wrocław

Ostrzeżenie: (0%)
-----


Route model binding: http://jenssegers.be/index.php/blog/52/lar...ding-is-awesome
Form request validation: https://laracasts.com/series/laravel-5-fund...als/episodes/12
Go to the top of the page
+Quote Post
konrados
post 11.06.2015, 20:44:53
Post #7





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


No nic, właśnie pomyślałem, że mogę przecież pójść swoją drogą (dziedziczenie zamiast wstrzykiwania) a potem dorobić wstrzykiwanie jeśli kiedyś okaże się, że (oprócz unit tests) są jakieś zalety tego wstrzykiwania.

Dzięki!
Go to the top of the page
+Quote Post
memory
post 11.06.2015, 20:50:08
Post #8





Grupa: Zarejestrowani
Postów: 616
Pomógł: 84
Dołączył: 29.11.2006
Skąd: bełchatów

Ostrzeżenie: (0%)
-----


@konrados po co potem jak można teraz
Go to the top of the page
+Quote Post
konrados
post 11.06.2015, 20:56:31
Post #9





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


@memory
Bo na razie widzę tylko jedną oczywistą zaletę - testowanie. A to trochę dla mnie za mało, mój framework ma być prosty a dziedziczenie jest proste i wszystkim znane smile.gif

Poza tym na pierwszy rzut oka dołożenie takiego wstrzykiwania nie złamie kompatybilności wstecznej - tzn. dołożę taką możliwość a nadal dotychczasowe rozwiązania będą działały. Czyli nie widzę wad:)
Go to the top of the page
+Quote Post
memory
post 11.06.2015, 21:19:15
Post #10





Grupa: Zarejestrowani
Postów: 616
Pomógł: 84
Dołączył: 29.11.2006
Skąd: bełchatów

Ostrzeżenie: (0%)
-----


Naprawde warto poczytać o dependency injection

Ten post edytował memory 11.06.2015, 21:19:25
Go to the top of the page
+Quote Post
konrados
post 11.06.2015, 21:39:00
Post #11





Grupa: Zarejestrowani
Postów: 623
Pomógł: 79
Dołączył: 16.01.2008

Ostrzeżenie: (0%)
-----


@memory

Dzięki, ale ja wiem co to jest. Tylko, że w tym konkretnym przypadku do mnie nie przemawia (na razie, wraz z doświadczeniem może przemówi).

Go to the top of the page
+Quote Post
com
post 11.06.2015, 23:50:57
Post #12





Grupa: Zarejestrowani
Postów: 3 034
Pomógł: 366
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


jak zrozumiesz DI to do Ciebie przemówi, uniezależniasz konkretne klasy od danej konkretnej implementacji. Tworzysz obiekt raz i operujesz w wielu miejscach aplikacji, dzięki temu możesz wywołać jakiegoś configa, czy cokolwiek na nim i masz pewność, że wszystkie dane będą ze sobą spójne. Ponadto możesz mieć kilka implementacji tego samego interfejsu i wykorzystać jeden kod w wielu miejscach bez manipulacji klasą, wystarczy podmienić tylko ten obiekt który przekazujesz.
Go to the top of the page
+Quote Post
by_ikar
post 12.06.2015, 07:24:55
Post #13





Grupa: Zarejestrowani
Postów: 1 798
Pomógł: 307
Dołączył: 13.05.2009
Skąd: Gubin/Wrocław

Ostrzeżenie: (0%)
-----


Jak dla mnie route model binding i form request valdiation są najlepszymi przykładami tego jak wstrzykiwanie obiektów jest przydatne. W kilku linijkach można napisać jakieś rest api, łącznie z validacją (nie tylko danych post), co jest mega.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 11:08