Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Traits w PHP
pitbull82
post 7.03.2012, 08:09:23
Post #1





Grupa: Zarejestrowani
Postów: 167
Pomógł: 0
Dołączył: 30.04.2004
Skąd: Częstochowa

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


Witam

Tak się zastanawiam nad przydatnością traits w php. Nie wiem czy dobrze rozumiem ideę, ale widzę ich zastosowanie jako np. zastąpienie globalnych funkcji zdefiniowanych przez użytkownika. Do tej pory można sobie było zdefiniować funkcję, ale nigdy nie było wiadomo czy w kolejnej wersji php nie wprowadzą funkcji o takiej samej nazwie i będzie problem. Teraz wystarczy dodać taką funkcję do traits i może być wykorzystana w klasach które tego potrzebują. Jako przykład traits widziałbym np. wrzucenie tam funkcji umożliwiających operacje na plikach/katalogach typu usuwanie katalogu z zawartością i potem wykorzystywanie w klasach które potrzebują takiej funkcjonalności.

Proszę o opinię czy dobrze to rozumiem. Może Wy macie jakieś inne pomysły/odczucia?

Pozdrawiam


--------------------
Go to the top of the page
+Quote Post
hind
post 7.03.2012, 08:16:15
Post #2





Grupa: Zarejestrowani
Postów: 142
Pomógł: 24
Dołączył: 30.03.2009
Skąd: Rokitno Szlacheckie

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


mechanizm Traits jest opisywany jako "kopiuj" i "wklej" kawałka kodu, umozliwia dziedziczenie po więcej niż jednej klasie (extends)
Go to the top of the page
+Quote Post
thek
post 7.03.2012, 09:52:46
Post #3





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Nie ma to jak sięgnąć do paru miejsc:
http://php.net/manual/en/language.oop5.traits.php
http://webhosting.pl/PHP.5.4.wprowadzi.obs...ch.%5Btraits%5D
http://blog.wsoczynski.pl/2011/03/22/jezyk...hp-pt-3-traits/
Przeczytawszy na pewno wiele wątpliwości rozwiejesz, ale w najprostszym wariancie to jest faktycznie umożliwienie różnym klasom dostępu do do tych samych funkcjonalności.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
skowron-line
post 7.03.2012, 09:55:56
Post #4





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


Do listy linków @thek -a dorzucę jeszcze
https://wiki.php.net/rfc/traits


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
wookieb
post 7.03.2012, 10:39:53
Post #5





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




http://forum.php.pl/index.php?s=&showt...st&p=908472


--------------------
Go to the top of the page
+Quote Post
mortus
post 7.03.2012, 13:54:20
Post #6





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Cytat(hind @ 7.03.2012, 08:16:15 ) *
umozliwia dziedziczenie po więcej niż jednej klasie (extends)

Niezupełnie, a już na pewno bez słówka extends. W PHP klasy mogą nadal dziedziczyć tylko po jednej klasie. Traits-y natomiast umożliwiają danej klasie przejęcie pewnych funkcjonalności i/lub cech, które może posiadać również inna klasa, zupełnie niezależna (nazywa się to dziedziczeniem poziomym). Traits-y to przeważnie zbiory tych funkcjonalności, a czasami zbiory pewnych ustawień (properties), jednakowych dla kilku różnych klas. Obiekt klasy A, posiadający trait B, nie jest obiektem klasy B, jak to jest w przypadku dziedziczenia pionowego.
Go to the top of the page
+Quote Post
wookieb
post 7.03.2012, 14:24:31
Post #7





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




@mortus w innych językach klasa dziedziczy również tożsamość traits-a (Ruby, Scala), czyli istnieje możliwość wykonania operacji
Kod
object instanceof TraitName; // true jeżeli używa traits-a


--------------------
Go to the top of the page
+Quote Post
mortus
post 7.03.2012, 14:35:36
Post #8





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

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


Cytat(wookieb @ 7.03.2012, 14:24:31 ) *
@mortus w innych językach klasa dziedziczy również tożsamość traits-a (Ruby, Scala), czyli istnieje możliwość wykonania operacji
Kod
object instanceof TraitName; // true jeżeli używa traits-a

Dobrze wierdzieć, bo myślałem, że jednak nie. Sprawdzę, jak jest w PHP, jak będę miał możliwość.
Go to the top of the page
+Quote Post
wookieb
post 7.03.2012, 14:38:53
Post #9





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




W php tak nie jest...


--------------------
Go to the top of the page
+Quote Post
thek
post 7.03.2012, 14:45:50
Post #10





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Dlatego idealnie do traitsa pasuje jego słówko dodające "use". Klasa więc używa traitsa i jego własności czy metod, które dostarcza. Do pewnego stopnia traitsy więc są natychmiast dostarczalną wersją interfejsów (choć same także modą mieć metody abstrakcyjne i coś wymuszać tym samym). O ile jednak interfejsy mówią, że klasa musi posiadać to czy tamto, o tyle traitsy mogą wprost już dać określone możliwości z samego faktu deklaracji jego użycia przez klasę. Część osób, nie bez powodów, widzi jego wykorzystanie w pewnych sytuacjach jako zastępnik Dependancy Injection Container.

@wookieb: fajna właściwość... i co najważniejsze - logiczna. W końcu jeśli klasa używa konkretnego traitsa, to można się posłużyć wszystkim co on udostępnia, więc można to nazwać instancją traitsa, która jest bogatsza o to, czego traits jest "częścią". Szkoda, że PHP nie idzie tą samą drogą...
Powód edycji: [thek]: Małe dopowiedzenia ;)


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
wookieb
post 7.03.2012, 14:54:48
Post #11





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Cytat(thek @ 7.03.2012, 14:45:50 ) *
@wookieb: fajna właściwość... i co najważniejsze - logiczna. W końcu jeśli klasa używa konkretnego traitsa, to można się posłużyć wszystkim co on udostępnia, więc można to nazwać instancją traitsa, która jest bogatsza o to, czego traits jest "częścią". Szkoda, że PHP nie idzie tą samą drogą...

Ale jest rozwiązanie. Traits + interface
http://www.slideshare.net/wookieb/iteratory slajd 32


--------------------
Go to the top of the page
+Quote Post
Crozin
post 7.03.2012, 15:11:24
Post #12





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Cytat
Do tej pory można sobie było zdefiniować funkcję, ale nigdy nie było wiadomo czy w kolejnej wersji php nie wprowadzą funkcji o takiej samej nazwie i będzie problem.
Narzędziem do rozwiązywania tego problemu są przestrzenie nazw.
Cytat
Jako przykład traits widziałbym np. wrzucenie tam funkcji umożliwiających operacje na plikach/katalogach typu usuwanie katalogu z zawartością i potem wykorzystywanie w klasach które potrzebują takiej funkcjonalności.
Takie rzeczy jak odczytywanie katalogów czy usuwanie plików to dosyć skomplikowane operacje i powinny być one wykonywane przez zupełnie osobne obiekty.

Cytat
Część osób, nie bez powodów, widzi jego wykorzystanie w pewnych sytuacjach jako zastępnik Dependancy Injection Container.
Mógłbyś podać przykład takiej sytuacji, bo szczerze powiedziawszy ciężko mi jest sobie to wyobrazić.
Cytat
@wookieb: fajna właściwość... i co najważniejsze - logiczna. W końcu jeśli klasa używa konkretnego traitsa, to można się posłużyć wszystkim co on udostępnia, więc można to nazwać instancją traitsa, która jest bogatsza o to, czego traits jest "częścią".
Nie do końca logiczna, bo PHP umożliwia manipulowanie tym traitsem (można to słówko jakoś sensownie tłumaczyć). Innymi słowy metoda zdefiniowana jako publiczna w traitsie może zostać "przestawiona" na prywatną w danej klasie. Jednak nawet nie to jest tutaj powodem - nigdy (nie potrafię znaleźć sytuacji poza jakimiś mechanizmami refleksji) nie powinno się interesować czy dany obiekt korzysta z traitsa czy nie - to jego wewnętrzna sprawa. W takich miejscach powinno użyć się interfejsów.

Co do samego pytania. Traitsy jakiejś wielkiej rewolucji nie wprowadzają - a przynajmniej nie powinny. Mało widzę dla nich sensownych zastosowań. Ale i w pewnych miejscach mogłyby być całkiem użyteczne. Gdzie? Na przykład przy domyślnej (albo jednej z predefiniowanej) implementacji interfejsu. Załóżmy, że mamy jakiś interfejs co do którego jesteśmy pewni, że większość jego implementacji będzie wyglądać dokładnie tak samo. Przykładowo interfejs Symfony\Component\DependencyInjection\ContainerAwareInterface. Niemal w całym (a może i w całym) frameworku jak i w kodach aplikacji na nim zrealizowanych ten interfejs jest implementowany w następujący sposób:
  1. class ... implements ContainerAwareInterface {
  2. private $container;
  3.  
  4. function setContainer(ContainerInterface $container = null) {
  5. $this->container = $container;
  6. }
  7. }
Nic by się nie stało gdyby istniał traits Symfony\Component\DependencyInjection\ContainerAwareInterfaceImplementation, wtedy w większości miejsc można by zastosować:
  1. class ... implements ContainerAwareInterface {
  2. use ContainerAwareInterfaceImplementation;
  3. }
Oczywiście wszędzie sprawdzałoby się czy dany obiekt implementuje interfejs ContainerAwareInterface, a nie traitsa ContainerAwareInterfaceImplementation.
Jednak nawet i tak nieinwazyjne zastosowanie ma wady - bo co jeśli ktoś zmieni definicję tego traitsa? Bardzo nieciekawy w diagnostyce problem.
Go to the top of the page
+Quote Post
thek
post 7.03.2012, 22:55:45
Post #13





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




@Crozin: W przypadku prostszych, mniejszych, aplikacji użycie DIC może być nieco sztuką dla sztuki, jeśli przewidujemy użycie raptem kilku możliwości, które są bardzo szablonowe. Przykładem takiego prostego rozwiązania jest zapis/odczyt danych. Jeśli mamy do czynienia naprawdę z kobyłą elastyczną - ma to sens, bo nigdy nie wiemy przecież co nam za źródło ostatecznie może posłużyć. Jeśli jednak znamy ograniczenia, możemy się ograniczyć do jednej klasy lub właśnie traitsa, który nam to połączenie ze źródłem umożliwi. Definiujemy sobie traitsa z tym połączeniem i już mamy spokój. Zwyczajnie dajemy use TraitsPołączenia klasie i zapominamy. Zauważ, że nie bez powodu pisząc swój tekst używałem słów: "może", "w określonych wypadkach/sytuacjach". Nie są to jedynie zabiegi stylistyczne z mojej strony i jestem świadom, że ma to rozwiązanie swoje wady i zalety.

To co potem rozważałeś to właśnie dobry przykład dla prostego serwisu. "Zapytałbym" o to, czy to co mnie interesuje ma traitsa RDBConnection i byłbym pewien co do możliwości operacji na jakiejś tam bazie danych, którą to ów traits by mi udostępniał. Owszem, mógłbym zamiast traitsa użyć osobnej klasy połączenia, DIC pozwalający mi na elastyczne podejście do tego, czy inne rozwiązanie problemu zaproponować, ale równie dobrze mogę użyć traitsa, który będzie równie zapewne prostszy i szybszy w implementacji niż elastyczniejsze ale przez to bardziej złożone mechanizmy.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
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: 24.07.2025 - 19:56