Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Obiektowość w PHP5, pytanie dotyczące interfejsów
Jarod
post 31.07.2006, 22:50:39
Post #1





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

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


Właśnie czytam sobie wprowadzenie do programowania obiektowego z ksiażki (PHP5 zaawansowane programowanie). Wiem jak tworzyć klasę, rozumiem hermetyzację (właściwośći public, private i protected), dziedziczenie nawet załapałem. Rozumiem zachowywanie właściwości przodka przez stosowanie parent::[nazwaFunkcji] itp.

Ale mam dwa pytania:

1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?

2. Nie mogę zrozumieć sensu istnienia interfejsu. Może w tej książce jest to beznadziejnie opisane ale sami zobaczcie. Autor pisze:

Cytat
(...)Mając uzgodniony zestaw metod, możemy sprawić, by zupełnie różne obiekty były przekazywane do tych samych funkcji bez potrzeby tworzenia między nimi relacji opartych na dziedziczeniu.(...)

i podaje taki przykład:

Plik interface.Openable.php
  1. <?php
  2. interface Openable {
  3. abstract function open();
  4. abstract function close();
  5. }
  6. ?>



Plik class.Door.php
  1. <?php
  2. require_once ('interface.Openable.php');
  3.  
  4. class Door implements Openable {
  5.  
  6. private $_locked = false;
  7.  
  8. public function open() {
  9. ...
  10. ...
  11. }
  12. public function close() {
  13. ..
  14. ...
  15. }
  16. public function lockDoor() {
  17. ...
  18. ...
  19. }
  20. public function unlockDoor() {
  21. ...
  22. ...
  23. }
  24. }
  25. ?>



Plik class.Jar.php
  1. <?php
  2. require_once ('interface.Openable.php');
  3.  
  4. class Jar implements Openable {
  5.  
  6. private $contents;
  7.  
  8. public function __construct($contents) {
  9.  
  10. $this->contents = $contents;
  11. }
  12. public function open() {
  13. ...
  14. ...
  15. }
  16. public function close() {
  17. ..
  18. ...
  19. }
  20. ?>


i wreszcie plik główny
testOpenable.php
  1. <?php
  2. require_once ('class.Door.php');
  3. require_once ('class.Jar.php');
  4.  
  5. function openSomething(Openable $obj)
  6.  {
  7. $obj -> open();
  8. }
  9.  
  10. $objDoor = new Door();
  11. $objJar = new Jar('galaretka');
  12.  
  13. openSomething($objDoor);
  14. openSomething($objJar);
  15. ?>



A następnie autor pisze:
Cytat
(...)Ponieważ zarówno klasa Door, jak i Jar implementują interfejs Openable, można przesłać obiekty każdej z tych klas do funkcji openSomething(). Ponieważ funcja ta akceptuje tylko coś, co implementuje interfejs Openable, wiemy, że możemy w jej ramach wywołać funkcję open() i close(). Nie należy jednak próbować dostępu do właściwości contents ani używać funkcji lock() lub unlock() z poziomu aplikacji funkcji openSomething(), ponieważ ta właściwość i te moetody nie są częścią interfejsu. (...)


Skoro możemy używać tylko tych metod, które zostały wymienione w interfejsie to po jakiego grzyba w klasach tworzył inne metody? Po co wogóle ten interfejs skor i tak powtarzamy kod. W klasie Door piszemy metodę open() i close() i w klasie Jar też piszemy. A w obiektowości chodzi m.in. o nie powielanie kodu (słowa autora).

Próbuje zrozumieć ten przykład, żeby nie mieć dalej problemów w następnych rozdziałąch, ale wydaje mi się to bez sensu.
Może mi to ktoś wytłumaczyć?


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Ludvik
post 31.07.2006, 22:56:21
Post #2





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

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


Cytat
1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?

Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc. Zmniejsza się ilość kodu podatnego na błędy... Prywatna po to, aby nikt nie odwołał się do metody, która nie ma nic wspólnego z prawdziwym interfejsem obiektu.

2. [...]
Interfejs mówi, które metody dana klasa musi udostępniać, a nie o całym interfejsie danej klasy. Znając intefejs klasy możemy być pewni, co ona potrafi zrobić. Nie wiemy natomiast, czy nie potrafi czegoś jeszcze... Tak to już bywa, że niektóre klasy są zgodne z interfejsem, lecz udostępniają jeszcze coś specjalnego. Dlatego właśnie autor dopisał te metody.


--------------------
Go to the top of the page
+Quote Post
Ja_Szczur
post 31.07.2006, 23:05:18
Post #3





Grupa: Zarejestrowani
Postów: 115
Pomógł: 0
Dołączył: 4.12.2005
Skąd: Strzyżów

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


1) głupi przykład, ale:
  1. <?php
  2. class engine
  3. {
  4.  //...
  5.  
  6.  private function deleteAll()
  7.  {
  8. // ...
  9.  }
  10. }
  11.  
  12. $e = new Engine;
  13. $e->load();
  14. $e->run();
  15.  
  16. // ale ze mnie żartowniś!
  17. $e->deleteAll();
  18. ?>


2) pomyśl o tym inaczej:
masz różne klasy, które reprezentują [implementują] marki samochodów [samochód - interfejs]
wymagasz od nich, żeby mogły jechać, otwierać drzwi, mieć klimatyzajcę itd. tongue.gif [metody wymagane w interfejsie]
chcesz pojechać samochodem: wybierając którąkolwiek klasę [mercedes, bmw, fiat] implementującą interfejs samochód, masz pewność, że jest tam metoda go() czy też run() - nie martwisz się o to!

czyli: masz kilka samochodów, jedne z klimatyzacją, inne z barkiem na pokładzie
ale wiesz jedno: wszystkie mają metody run() openDoors() i np. szlagTrafilSilnik() biggrin.gif

jeżleli za ciemno wyjaśniłem, daj znać, rzucę przykład na systemie newsów w cms'ie czy coś :]


--------------------
"No bo z fasolą to człowiek przynajmniej wie, na czym stoi..."
Pomniejsze bóstwa, Terry Pratchett

php :*
Go to the top of the page
+Quote Post
mike
post 31.07.2006, 23:07:14
Post #4





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Przenoszę z Przedszkola na php :: PHP5
Go to the top of the page
+Quote Post
nazihipi
post 31.07.2006, 23:34:28
Post #5





Grupa: Zarejestrowani
Postów: 139
Pomógł: 0
Dołączył: 14.07.2006

Ostrzeżenie: (10%)
X----


Cytat
1. Domyślnie funkcje, tzn metody są domyślnie public. To, że właściwości mogą być np private jest dla mnie zrozumiałe. Ale czy jest sens tworzyć metodę private? Po co?


1. po to abyś nie miał do niej dostępu z zewnątrz
2. aby nie została odziedziczona

Cytat
Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc. Zmniejsza się ilość kodu podatnego na błędy...

do tego wcale nie potrzeba prywatnej metody...
Go to the top of the page
+Quote Post
Ludvik
post 31.07.2006, 23:37:00
Post #6





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

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


No oczywiście, że nie potrzeba prywatnej metody. Najlepiej, kiedy ktoś sobie z zewnątrz wywoła metodę, która namiesza wewnątrz klasy... A jak ją odziedziczy, to też fajnie jest smile.gif


--------------------
Go to the top of the page
+Quote Post
nazihipi
post 31.07.2006, 23:46:37
Post #7





Grupa: Zarejestrowani
Postów: 139
Pomógł: 0
Dołączył: 14.07.2006

Ostrzeżenie: (10%)
X----


oczywiście, logiczna sprawą jest, że chroniony kod umieszcze się w metodach prywatnych...

z twojej wypowiedzi jednak można zrozumieć, że "powtarzający się kod w metodach publicznych możemy sobie przenieść do metod prywatnych, bo będzie szybciej." cool.gif

dopiero tu jest sens
Cytat
Prywatna po to, aby nikt nie odwołał się do metody


nie ważne winksmiley.jpg pozdrawiam
Go to the top of the page
+Quote Post
TomASS
post 1.08.2006, 00:49:26
Post #8





Grupa: Zarejestrowani
Postów: 1 660
Pomógł: 13
Dołączył: 9.06.2004
Skąd: Wrocław i okolice

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


Co do interfejsów, to dodam jeszcze swoje trzy grosze.

W php (niestety) obiekt nie może dziedziczyć po kilku rodzicach (jak ma to miejsce np. w C++) - może dziedziczyć (jak narazie) tylko po jednym rodzicu. Jest jeden myk - można właśnie do tego używać interfejsów. Obiekt może posiadać wiele interfejsów.

Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.

smile.gif Chyba nie zamieszałem za bardzo smile.gif


--------------------
Go to the top of the page
+Quote Post
NuLL
post 1.08.2006, 03:07:30
Post #9





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

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


Cytat
Nie mogę zrozumieć sensu istnienia interfejsu. Może w tej książce jest to beznadziejnie opisane ale sami zobaczcie. Autor pisze:

Hardcorowa ta ksiazka - albo tlumacz nie mial pojecia o programowaniu albo autor sie zakrecil winksmiley.jpg

Interfejs pozwala wymusic na obiekcie posiadanie okreslonych metod - przydaje sie to np przy pisaniu sterownikow - zakladasz ze klasa musi implementowac interfejs IDriver ktory posiada okreslone metody aby dana klasa mogla byc sterownikiem smile.gif Tam gdzie musisz sobie stworzyc sterownik ( np. w glownej klasie DB aby mozna bylo obluzyc MySQLa i PostgreSQLa ) sprawdzasz czy posiada ona okreslone metody - a robisz to sprawdzajac czy implementuje danych interfejs dzieki f-cji class_implements" title="Zobacz w manualu php" target="_manual Rkingsmiley.png

Cytat
W php (niestety) obiekt nie może dziedziczyć po kilku rodzicach (jak ma to miejsce np. w C++) - może dziedziczyć (jak narazie) tylko po jednym rodzicu. Jest jeden myk - można właśnie do tego używać interfejsów. Obiekt może posiadać wiele interfejsów.Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.

Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze tongue.gif

Ten post edytował NuLL 1.08.2006, 03:16:25


--------------------
Javascript, Coffeescript, Node.js, Mongo, CouchDb, chmury, workery & inne bajery - zycie jest zbyt krotkie aby miec nudna prace :)
Go to the top of the page
+Quote Post
nazihipi
post 1.08.2006, 09:09:57
Post #10





Grupa: Zarejestrowani
Postów: 139
Pomógł: 0
Dołączył: 14.07.2006

Ostrzeżenie: (10%)
X----


Cytat
Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze

w pewnym sensie interfejsy można potraktować jako zastępnik wielodziedziczenia;
istnieje także inna właściwość dziedziczenia (nie tylko optymalizacja) mianowicie to, że wiesz do jakich metod klasa dziedzicząca ma dostęp; w tym przykładzie zadanie to spełniają interfejsy
Go to the top of the page
+Quote Post
Athlan
post 1.08.2006, 09:39:13
Post #11





Grupa: Developerzy
Postów: 823
Pomógł: 12
Dołączył: 18.12.2005

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


Cytat
Masz np. interfejs do budynków, który mówi, że klasa z interfejsem budynek musi zawierać metody buduj() oraz zburz(), dodatkow masz interfejs np. supermarket - klasa musi zawierać metody otworz() zamknij i teraz masz np. właśnie supermarket do którego możesz podłączyć interfejs budyku i supermarketu.


wszyscy nawiązują do świata realnego, a podajcie przykłady odnośnie zastosowania tego w CMS'ie, albo frameworku, bo ci którzy wiedzą o co biega nie maja problemu zrozumieć... przecież uzywali tego już w kodzie, ale jak tego użyć, do czego to właściwie może się przydać to już nikt nie pisze... w żadnej książce i w żadnym artykule o OOP

pozdrawiam smile.gif

p.s. proszę wziąźć sobię tą uwagę do serca (mówie do tych którzy radzą, ale niejaśnie jak im się zdaje smile.gif )

Ten post edytował Athlan 1.08.2006, 09:40:44


--------------------
Portfolio: Vgroup.pl | athlan.pl | Test.php.pl - sprawdź się z wiedzy o PHP i ułóż własne pytania!
Pomogłem? Kliknij pod postem.
Go to the top of the page
+Quote Post
Ludvik
post 1.08.2006, 09:58:02
Post #12





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

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


Tworzysz kontener dla danych, który możesz zserializować, odwoływać się do niego jak do tablicy oraz iterować go. Musisz zaimplementować interfejsy Serializable, ArrayAccess (nie pamiętam czy tylko ten do tablicy...) oraz Iterator.

Tworzysz system newsów z jednolitym cache udostępnianym dla każdego obiektu. Każdy news musi implementować i interfejs newsa i Cache...

Przykładów można dużo znaleźć, chociaż nie wszystko jest do końca poprawne (przykład newsów) z założeniami OOP. Jedna klasa = jedna odpowiedzialność. Tutaj tak nie jest. Ale zdarzają się miejsca, w których interfejsy zostają rozdrobnione i po złączeniu ich dostajemy obiekt, który wciąż jest odpowiedzialny tylko za jedno.


--------------------
Go to the top of the page
+Quote Post
TomASS
post 1.08.2006, 10:27:06
Post #13





Grupa: Zarejestrowani
Postów: 1 660
Pomógł: 13
Dołączył: 9.06.2004
Skąd: Wrocław i okolice

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


Cytat
Implementowanie wielu interfejsow nie ma nic wspolnego z wielodziedziczwniem. Implementowanie wielu interfejsow i tak wymaga napisania calego kodu - wiec co ma piernik do wiatraka questionmark.gif Dziedzicznie pozwala m.in uniknac nadmiaru kodu - a ja tu niczego takiego nie widze tongue.gif


Dobrze wiesz, że nie o to mi chodziło tongue.gif Oczywiście, że implementowanie wielu interfejsów wymaga napisania całego kodu, ale przecierz to nie jedyny sens dziedziczenia. Jeśli chcesz aby określona klasa zawierała określone metody w celu współgrania z innymi częściami systemu, musisz to jej jakoś narzucicić. Dla mnie dziedziczenie po dwóch rodzicach można rozwiązać tylko poprzez interfejsy - chociaż zaznaczam, że to takie "para dziedziczenie".

Cytat
w pewnym sensie interfejsy można potraktować jako zastępnik wielodziedziczenia;
istnieje także inna właściwość dziedziczenia (nie tylko optymalizacja) mianowicie to, że wiesz do jakich metod klasa dziedzicząca ma dostęp; w tym przykładzie zadanie to spełniają interfejsy

Dokładnie

Chociaż drogi Nullu zgadzam się z Tobą w 99% tongue.gif


--------------------
Go to the top of the page
+Quote Post
athabus
post 1.08.2006, 17:29:01
Post #14





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

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


Ja tu jeszcze dodam 3 grosze... W php5 dodano opcję, dzięki której można wymagać aby zmienna przekazywana do metody miała określony typ. Typem może być również interfejs - czyli dajmy na to projektujemy stronę. Strona może wyświetlać różne rzeczy - np. nowości, artykuły, ostrzeżenia dla użytkowników itp.

Załóżmy, że masz obiekt strona, który posiada funkcję display() odpowiedzialną za wyświetlenie czegoś. Aby uniknąć jakiegoś błędu typu próba wyświetlenia czegoś co nie powinno być wyświetlane, możesz w funkcji display ograniczyc parametry tylko do obiektow inmplementujących określony interfejs, np. Idisplayable.

Ciekawym zastosowaniem interfejsów jest również wzorzec obserwatora. W podanym linku użytko akurat klas Observer i Observable - ale z powodzeniem można je zastąpić interfejsami.
Go to the top of the page
+Quote Post
Jarod
post 1.08.2006, 20:59:46
Post #15





Grupa: Zarejestrowani
Postów: 1 190
Pomógł: 27
Dołączył: 23.04.2005

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


Cytat(Ludvik @ 31.07.2006, 21:56 ) *

Czasami zdarzają się takie przypadki, gdzie w wielu publicznych metodach powtarza się ten sam kod. Wtedy możesz jednkrotnie napisać go w metodzie prywatnej i wywoływać ją z odpowiednich miejsc.


Metody publiczne też możesz wywoływać z odpowiednich miejsc. To Ty piszesz kod, więc wiesz co robisz..
Cytat(Ludvik @ 31.07.2006, 21:56 ) *
2. [...]
Interfejs mówi, które metody dana klasa musi udostępniać, a nie o całym interfejsie danej klasy. Znając intefejs klasy możemy być pewni, co ona potrafi zrobić. Nie wiemy natomiast, czy nie potrafi czegoś jeszcze... Tak to już bywa, że niektóre klasy są zgodne z interfejsem, lecz udostępniają jeszcze coś specjalnego. Dlatego właśnie autor dopisał te metody.


Ale co z tego, że udostępniają coś jeszcze, skoro nie można się do nich odwoływać, bo nie są wymienione w interfejsie?

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
1) głupi przykład, ale:
  1. <?php
  2. class engine
  3. {
  4.  //...
  5.  
  6.  private function deleteAll()
  7.  {
  8. // ...
  9.  }
  10. }
  11.  
  12. $e = new Engine;
  13. $e->load();
  14. $e->run();
  15.  
  16. // ale ze mnie żartowniś!
  17. $e->deleteAll();
  18. ?>


Dobry przykład. Dziękuje.

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
2) pomyśl o tym inaczej:
masz różne klasy, które reprezentują [implementują] marki samochodów [samochód - interfejs]
wymagasz od nich, żeby mogły jechać, otwierać drzwi, mieć klimatyzajcę itd. tongue.gif [metody wymagane w interfejsie]
chcesz pojechać samochodem: wybierając którąkolwiek klasę [mercedes, bmw, fiat] implementującą interfejs samochód, masz pewność, że jest tam metoda go() czy też run() - nie martwisz się o to!

czyli: masz kilka samochodów, jedne z klimatyzacją, inne z barkiem na pokładzie
ale wiesz jedno: wszystkie mają metody run() openDoors() i np. szlagTrafilSilnik() biggrin.gif


Ale ograniczasz się. Nie możesz wykonywać metod, które nie zostały podane w interfejsie. Czy nie lepiej poprostu zbudować podstawową klasę Samochód, która będzie zawierała run(), openDoors() a np klasa Mercedes dziedziczy po klasie Samochod i dodaje nowe metody? Przecież to o wiele prostrze..

Cytat(Ja_Szczur @ 31.07.2006, 22:05 ) *
jeżleli za ciemno wyjaśniłem, daj znać, rzucę przykład na systemie newsów w cms'ie czy coś :]


Jeśli nie mogę zrozumieć sensu interfejsu to myślisz, że połapie się w kodzie jakiegoś CMSa? tongue.gif


--------------------
”Godzina nauki w życiu nowoczesnego apostoła jest godziną modlitwy.”
(św. Josemaría Escrivá, Droga, 335)
Go to the top of the page
+Quote Post
Cysiaczek
post 1.08.2006, 21:15:57
Post #16





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Zgodze się z Athabusem - klasa implementująca interfejs zyskuje dodatkowy typ, który można potem wymusić gdzieś, lub po prostu sprawdzić. Może to być bardzo przydatne, zwłaszcza, gdy pracujesz na kilku zupełnie ze sobą niepowiązanych obiektach. Będziesz dla nich robił klasę abstrakcyjną? Po co? Niech implementują wspólny interfejs - po tym je poznasz.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
bigZbig
post 2.08.2006, 07:42:32
Post #17





Grupa: Zarejestrowani
Postów: 740
Pomógł: 15
Dołączył: 23.08.2004
Skąd: Poznań

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


Cytat(J4r0d @ 1.08.2006, 21:59 ) *
Ale ograniczasz się. Nie możesz wykonywać metod, które nie zostały podane w interfejsie. Czy nie lepiej poprostu zbudować podstawową klasę Samochód, która będzie zawierała run(), openDoors() a np klasa Mercedes dziedziczy po klasie Samochod i dodaje nowe metody? Przecież to o wiele prostrze..

Interfejs to taki regulamin, ktory okresla jakie metody powinna zawierac klasa, ktora dany interfejs implementuje. Patrzysz na naglowek klasy widzisz ze implementuje interfejs X i wiesz ze napewno ma ona metody, ktorych interfejs X wymaga. Czy Ty zgodnosc metod osiagniesz poprzez dziedziczenie czy np. za pomoca wzorca dekoratora to juz jest Twoja sprawa.


--------------------
bigZbig (Zbigniew Heintze) | blog.heintze.pl
Go to the top of the page
+Quote Post
athabus
post 2.08.2006, 08:49:48
Post #18





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

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


Cytat(J4r0d @ 1.08.2006, 19:59 ) *
Metody publiczne też możesz wywoływać z odpowiednich miejsc. To Ty piszesz kod, więc wiesz co robisz..


Takie myślenie zawiera pewne błędy
a ) Nie koniecznie to Ty piszesz kod - albo możesz go nie pisać samodzielnie
b ) Kod, który piszesz możesz chcieć wykorzystać za 2 lata - pytanie czy będziesz wtedy miał czas znowu się przegryzać przez to co może zrobić obiekt, czego nie. Które metody miały być wywoływane, a które są publiczne dlatego, że hmmm są itd.
c ) Twój kod być może będą wykorzystywać inne osoby (oczywiście za Twoją zgodą) - wtedy j.w.

Generalnie interfejsy są jednym z narzędzi nowowczesnych języków, które pozwalają na upraszczanie (grupowanie) zależności w kodzie, wymuszania na obiektach danej grupy posiadania pewnych funkcji itp.

Kiedyś czytałem taką książkę o UML, w której autor napisał, że ludzie nie są w stanie ogranąć złożoności, dlatego naturalnym jest, że zjawiska złożone strają się generalizować i grupować. Np. nie rozważają każdej marki samochodu z osobna (z jej wszystkimi bajerami itd) tylko generalizują sobie to do abstakcyjnego pojęcia samochodu czy pojazdu, które w większości przypadków wystarcza - samochód może się przemieszczać, ma silnik, koła itd. W programowaniu stosujemy klasy abstrakcyjne i interfejsy i dziedziczenie w tym samym celu - uproszczenia złożoności.

Inna Kwestia, że takich rzeczy używa się zazwyczaj w większych projektach lub w projektach nad którymi pracuje kilka osób. Jeśli nie czujesz jeszcze potrzeby generalizowania w swoich projektach to prawdopodobnie nie potrzebujesz tego. Ja akurat zacząłem stosować tego typu rozwiązania w C# i uważam, że w php jest znacznie mniej potrzeb wykorzystania tych konstrukcji (pewnie dlatego, że jeszcze słobo znam php i moje projekty nie są zbyt rozbudowane) niż w językach typu C#, C++ czy Java, choć i w php ostatnio zaczynam z nich korzystać coraz częściej.

Ten post edytował athabus 2.08.2006, 08:53:48
Go to the top of the page
+Quote Post
Ludvik
post 3.08.2006, 10:05:16
Post #19





Grupa: Przyjaciele php.pl
Postów: 698
Pomógł: 3
Dołączył: 28.03.2004
Skąd: Wrocław

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


J4rod: Pisząc kod jest naturalnym, że staramy się uczynić go maksymalnie idiotoodpornym. Czynienie publicznymi metod, które mają sens tylko wewnątrz klasy jest bezsensownym i nikt zdrowy czegoś takiego nie robi... Myślałem, że jest oczywiste, że klasa ma swój interfejs, czyli to co klient może zrobić z obiektem, oraz ukryte przed użytkownikiem szczegóły jej działania... Interfejs powinien być publiczny, a cała reszta prywatna/chroniona. I nie chodzi mi o interfejs w sensie konstrukcji językowej...

Pamiętaj też, że interfejs wymusza zaimplementowanie metod, ale nie broni implementowania tych, które nie zostały w nim wymienione. Możesz się do nich zawsze odwołać, ale musisz mieć pewność, że wiesz co robisz.

  1. <?php
  2. interface Iface {
  3. public function methodOne();
  4. public function methodTwo();
  5. }
  6.  
  7. class ClassOne implements Iface {
  8. public function methodOne() {}
  9. public function methodTwo() {}
  10. }
  11.  
  12. class ClassTwo implements Iface {
  13. public function methodOne() {}
  14. public function methodTwo() {}
  15. public function methodThree() {}
  16. }
  17.  
  18. class ClassThree extends ClassTwo {
  19. }
  20.  
  21. function funcOne(Iface $o) {
  22. $o->methodOne(); // Zawsze OK
  23. $o->methodTwo(); // Zawsze OK
  24. $o->methodThree(); // Niepewne wywołanie... Zwróci błąd w przypadku ClassOne.
  25. }
  26.  
  27. function funcTwo(ClassTwo $o) {
  28. $o->methodOne(); // Zawsze OK
  29. $o->methodTwo(); // Zawsze OK
  30. $o->methodThree(); // Zawsze OK, bo kontrola typów nie dopuści ClassOne
  31. }
  32. ?>


Ten post edytował Ludvik 3.08.2006, 10:07:26


--------------------
Go to the top of the page
+Quote Post
dr_bonzo
post 3.08.2006, 10:59:38
Post #20





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Cytat
Skoro możemy używać tylko tych metod, które zostały wymienione w interfejsie to po jakiego grzyba w klasach tworzył inne metody?

W Javie to widac:

  1. <?php
  2. interface Observer
  3. {
  4. public void update( $cos );
  5. }
  6.  
  7. class Window implements Observer
  8. {
  9. // cholercia, jak ja dawno nie kodowalem...
  10. public void open() {....}
  11. public void rename( $newName ) {....}
  12. public void update( $cos )
  13.  {
  14.  .... blalbabla..
  15.  }
  16. }
  17.  
  18. class Foo implements Observer
  19. {
  20.  public void bar() {...}
  21. public void update( $cos )
  22.  {
  23.  .... blalbabla..
  24.  }
  25. }
  26.  
  27. class Model extends Observable
  28. {
  29.  public boolean registerObserver( Observable obj )
  30.  {
  31. // tutaj dla $obj mozesz wywolac TYLKO metody z interfejsu Observable
  32. obj.update();
  33. // obj.bar() nie przejdzie
  34. }
  35. }
  36.  
  37. Window window = new Window();
  38. Foo foo = new Foo();
  39.  
  40. window.open();
  41. window.rename( "lol" );
  42. foo.bar();
  43.  
  44. Model model = new Model();
  45. model.registerObserver( window );
  46. model.registerObserver( foo );
  47. ?>


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
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: 20.06.2025 - 12:46