![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
![]() Grupa: Zarejestrowani Postów: 96 Pomógł: 3 Dołączył: 15.04.2003 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Ostatnio natknąłem się na artykuł, mówiący, że interfejsy w PHP są zbędne bo w skrócie ... nie działają jak w "Dżawie" (linka nie przytocze), więc podaje moje 2 zastosowania jakie znalazłem dla interfejsów w PHP. Odrazu zaznaczam, że mój post przeznaczony jest dla początkujących,
1. Interfejs warto zdefiniować jeżeli dajemy programiście możliwość zastąpienia jednej klasy inną zdefiniowaną przez programiste. Coż nie wiem jak to ładnie napisać żeby było fachowo, więc posłuże się przykładem. W Zend Framework-u domyślny widok (Zend_View) można zastpić dowolnym systemem szablonów np. Smarty. Jednak żeby to było możliwe Smarty musi być kompatybilne z Zend_View, i tu wkracza Zend_View_Interface, wystarczy, że Smarty będzie go implementować i może być wykorzystane w ZF (oczywiście pozostaje jeszcze stworzenie tej implementacji ale to już inna historia), więcej na ten temat napisane jest w manualu Zend View. 2. Nie lubie przykładów oderwanych od rzeczywistości, ale nic lepszego nie wymyśliłem, a więc ... Załóżmy, że mamy klasę Zoo do której metodą addAnimal będziemy dodawać zwierzęta, jednocześnie chcemy kontrolować czy dodawane zwierze jest obiektem odpowiedniego typu, ale każdy gatunek jest reprezentowany inną klasą (małpa - Monkey, tygrys - Tiger itd). Z takiego problemu możemy wybrnąć stosując interfejs Animal, który będą implementować klasy reprezentujące gatunki zwierząt.
Zapraszam do dyskusji. -------------------- Linux is like wigwam, no windows, no gates and an apache inside.
Mój blog łebmasterski (po angielsku) Web Development Blog. |
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 6 072 Pomógł: 861 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza ![]() |
Moim zdaniem przykład nie jest do końca trafiony. Lepiej chyba by było w tym przypadku zastosować dziedziczenie niż implementację interfejsu. Według mnie lepszym przykładem może być np. mechanizm wysyłający informacje różnymi metodami (sms, e-mail):
aczkolwiek nie wiem czy w dobrym stopniu prezentuje ideę interfejsów. Ogólnie chodzi o to, że implementacje interfejsu wymusza posiadanie przez klasę wszystkich metod definiowanych przez interfejs. W przypadku podanym przeze mnie jest to metoda getTo(). Nieważne co się dzieje w poszczególnych klasach - ważne, że jest możliwość zwrócenia przez każdą z nich ciągu reprezentującego odbiorcę wiadomości. Ten post edytował phpion 14.01.2009, 18:40:06 |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 96 Pomógł: 3 Dołączył: 15.04.2003 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Rzeczywiście Twój przykład wydaje sie być o niebo lepszy, mój cóż posłuży za przykład kiedy nie stosować interfejsów
![]() ![]() -------------------- Linux is like wigwam, no windows, no gates and an apache inside.
Mój blog łebmasterski (po angielsku) Web Development Blog. |
|
|
![]()
Post
#4
|
|
![]() Grupa: Zarejestrowani Postów: 226 Pomógł: 25 Dołączył: 4.07.2007 Skąd: Berlin Ostrzeżenie: (0%) ![]() ![]() |
Osobiście z interfejsów korzystam gdy piszę klasę z adapterami. Wtedy jak zapomnisz o jakiejś metodzie itp. PHP wywali błąd.
Ten post edytował bartg 20.01.2009, 20:47:56 -------------------- |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 206 Pomógł: 18 Dołączył: 6.03.2006 Skąd: Szczecin Ostrzeżenie: (0%) ![]() ![]() |
Interfejsy w PHP są nie tyle zbędne, co tak jak reszta obiektówki w nim - po prostu kulawe, albo przestrzelone (wystarczy chwila namysłu, przecież wszystko co w PHP nam przeszkadza zazwyczaj jest spowodowane tym, że główna idea PHP jest taka, aby był on dynamiczny, a tutaj interfejsy, które na nas coś wymuszają...). Poza tym brak w PHP możliwości type-hintingu dla zwracanych wartości funkcji dodatkowo przeszkadza w zwiększaniu użyteczności interfejsów. Ale oczywiście tak jak tutaj wszyscy już napisali są momenty kiedy się przydają.
Najczęściej oczywiście w przypadku, gdy udostępniamy nasz kod na zewnątrz, dajemy innym możliwość korzystania z niego, albo wręcz jego modyfikacji/rozbudowy. Co do użycia to trzeba pamiętać, że interfejs to twór czysto abstrakcyjny. Określa jedynie sposoby wykorzystania bez żadnej namiastki implementacji. Dlatego tak jak phpion powiedział, w przypadku Animal -> Monkey bardziej naturalne (i imho poprawne) byłoby użycie dziedziczenia - zwierzę to już jakiś (jak bardzo ogólny to nie ważne, ale jednak) byt, który nam od razu przywodzi na myśl jakieś zyjące stworzenie z kończynami i tak dalej... Skoro już tak z tymi zwierzętami to ja bym zaproponował inną nieco strategię podziału, żeby zobrazować interfejsy:
Z bardziej realnych i praktycznych przykładów: tworzę system wymiany ofert dla biur nieruchomości i metody wymiany ofert są przeróżne. System, żeby ułatwić integrację z już istniejącymi mechanizmami powinien obsługiwać obecne metody synchronizacji (serwisów w stylu Gratka.pl, OtoDom.pl i tak dalej). I jedne eksporty opierają na plikach XML, inne na API w SOAP'ie, jeszcze inne na plikach we własnym INI-podobnym formacie. A jednak wszystkie "sterowniki" eksportu muszą udostępniać jednakowy interfejs. Poglądowo mniej więcej:
(tutaj co najważniejsze chciałem pokazać, że Intefejsy pozwalają nam na użycie typowania instancji (type-hinting, instanceof i tak dalej) mimo dziedziczenia - w PHP nie ma dziedziczenia wielobazowego, ale interfejsów możemy implementować do woli, dlatego czasem są takie przydatne) Ten post edytował wrzasq 21.01.2009, 01:58:43 -------------------- Wrzasq.pl
Tworzenie stron i aplikacji internetowych. Chillout Development - tworzenie stron i aplikacji internetowych. |
|
|
![]()
Post
#6
|
|
![]() Grupa: Zarejestrowani Postów: 7 Pomógł: 1 Dołączył: 29.09.2008 Skąd: Świdnica Ostrzeżenie: (0%) ![]() ![]() |
Ja używanie interfejsów postrzegam przez pojęcie Roli jaką pełni klasa/interfejs w aplikacji. To bardzo przydatna strukturka, która uzmysławia nam co dzieje się w aplikacji w bardzo ogólny sposób. Jeśli dobrze zdefiniujemy interfejsy inni programiści łatwiej dojdą do tego jaka jest struktura ogólna aplikacji, jaki jest sposób komunikacji poszczególnych klas czy nawet klas zgrupowanych w moduły. Jest to odzwierciedlenie Komunikacji między klasami. A to że nazywamy to interfejsem również jest nie bez znaczenia - interfejs jako dostęp do czegoś innego, u nas - dostęp do klas. Interfejsem mogłaby być klasa z pustymi metodami, ale nazwyając rzeczy po imieniu wiemy odrazu o co chodzi.
Interfejs niczego nie wymusza, on pomaga - jeśli nie chcesz to go nie stosujesz, jeśli wiesz jak zastosować to stosujesz ![]() Ja z reguły zaczynam pisanie aplikacji właśnie od interfejsów, oczywiście mówię o większych aplikacjach w których liczba klas przekracza np. 30 klas. W takiej aplikacji zależności między klasami potrafią być już dosyć zagmatwane i definiowanie interfejsów porządkuje całość zarówno wizualnie jak i projektowo. Dodatkowo zawsze staram się projektować tak aby rozszerzanie aplikacji polegało na dodawaniu nowych klas a nie na potrzebie modyfikacji już istniejących, z takim podejściem idea interfejsów sprawdza się znakomicie. Zdefiniowany interfejs jednoznacznie określa co musimy zrobić aby rozszerzyć funkcje jakiegoś modułu/klasy który/która komunikuje się z innymi. Przykład który podał phpion właśnie odzwierciedla tą ideę. Moglibyśmy dodać do niego jeszcze klasę Post{} która byłaby "reprezentacją" poczty - bytu który istnieje fizycznie. Idea interfejsów ma wiele zagadnień projektowych. Przypomnę tylko, że czasami trzeba rozpatrzeć to z jakiego punktu patrzymy na to co się dzieje w aplikacji i wtedy zastosować interfejs do odseparowania klas i utworzenia kanału komunikacyjnego za pomocą interfejsów. -------------------- |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 217 Pomógł: 23 Dołączył: 2.12.2007 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Interfejsy z powodzeniem stosuję we wzorcach projektowych, np Decorator. Można się nauczyć po co stosować i jak, jednak troszkę trzeba kodu popisać
![]() -------------------- Masz swoje mieszkanie i chcesz je wynająć? Sprawdź ofertę Zarzadządzanie Najmem
WRONA.IT - pozycjonowanie stron www.ecyklopedia.pl |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 31 Pomógł: 3 Dołączył: 24.03.2009 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
strategię podziału, żeby zobrazować interfejsy:
Chyba powinno być class AirPlane implements Flying Głupio że pierwszy mój post na forum to czepianie się ![]() |
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 48 Pomógł: 9 Dołączył: 7.03.2009 Skąd: Łódź Ostrzeżenie: (0%) ![]() ![]() |
Witam!
W PHP rzeczywiście interfejsy nie przypominają tych z Javy, czy rozwiązań z innych języków (np. mixiny w Ruby on Rails). Tutaj interfejs oznacza dodatkowe warunki do jakich musi zastosować się klasa. Klasycznym przykładem jest tzw. wzorzec obserwatora oparty na tzw. singletonie. Klasa, która chce użyć singletona musi implementować interfejs z prototypem funkcji, a sama w sobie musi tej funkcji nadać "ciało". Oto przykład Andiego Gutmansa - jednego z ojców php ( warto go przerobić i umieć jak pacierz ): <?php interface Observer { function notify($obj); } class ExchangeRate { static private $instance = NULL; # Zmienna singletona private $observers = array(); # Tablica rejestrująca klasy implementujące interfejs private $exchange_rate; #zmienna do funkcji function setExchangeRate($new_rate) private function ExchangeRate() { } static public function getInstance() { # Singleton if (self::$instance == NULL) { self::$instance = new ExchangeRate(); } return self::$instance; } public function getExchangeRate() { return $this->$exchange_rate; } public function setExchangeRate($new_rate) { $this->$exchange_rate = $new_rate; $this->notifyObservers(); } public function registerObserver($obj) { $this->observers[] = $obj; } function notifyObservers() { foreach($this->observers as $obj) { $obj->notify($this); } } } class ProductItem implements Observer { public function __construct() { ExchangeRate::getInstance()->registerObserver($this); } public function notify($obj) { if ($obj instanceof ExchangeRate) { // Uaktualnij dane dotyczące kursu walut print "Otrzymano aktualizację!\n"; } } } $productl = new ProductItem(); $product2 = new ProductItem(); ExchangeRate::getInstance()->setExchangeRate(4.5); ?> Wszystkie klasy implementujące interfejs i zarejestrowane poprzez ExchangeRate::getInstance()->registerObserver($this); muszą mieć zdefiniowaną funkcję notify(); Dzięki temu będą instancje tych klas powiadamiane o zmianach wprowadzonych poprzez funkcję: function setExchangeRate($new_rate). Najpopularniejsze wykorzystanie powyższego to informowanie w sklepie internetowym obiektów (tych, które powinny tą informację otrzymać) o zajściu zmian np. kursu waluty. Dzięki temu zostaną automatycznie wszędzie przeliczone ceny. Ten post edytował korkie 30.04.2009, 19:34:06 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 22.08.2025 - 07:10 |