Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: interfejsy to ściema ?
Forum PHP.pl > Forum > PHP > Object-oriented programming
Nortonek
Witam

cały czas nurtuje mnie pytanie i poczucie świadomości że interfejsy to jakaś totalna bzdura,

niby służą one do wielodziedziczenia (dla mnie oznacza to oszczędność czasu i mniej kodu)

ale jakoś nie mogę tego pojąć


pisanie tysięcy linijek kodu zawsze od zera, gdzie tu logika

interfejs A ma 300 metod, interfejs B ma 300 metod, interfejs C ma 300 metod, interfejs D ma 300 metod

i teraz robię 1 klasę ABCD, która implementuje te 4 interfejsy i piszemy w niej 1200 metod od zera

po czym w kolejnej klasie ABCD_v2 chcemy wykorzystać te same metody i niestety ale musimy je napisać znowu od zera jeszcze raz

czy na tym to polega ?
sowiq
Skoro masz klasy z 300 metodami, to znaczy, że coś robisz źle już od podstaw smile.gif To zdecydowanie za dużo funkcjonalności jak na jedną klasę.

Tak na prawdę interfejs ma być ograniczeniem zakładanym na klasy i jednocześnie mechanizmem, który zapewni poprawność napisanej klasy (która go implementuje).

Załóżmy, że robisz bloga. W dobrze zaprojektowanym projekcie masz adapter do operacji na danych (zapis, odczyt). Nie powinno Cię interesować czy zapisuje on do bazy, pliku XML, pliku CSV itp. Masz mieć tylko 3 metody - write, read, find.
Jeśli stworzysz sobie interfejs, który będzie wymuszał implementację tych metod, to na jego podstawie możesz tworzyć różne silniki do operacji na Twoich danych. Jeśli wszystkie będą implementowały ten sam interfejs, to masz pewność że sposób komunikacji z tymi klasami będzie identyczny. Nie będziesz musiał po zmianie zapisu z XML na bazę danych przerabiać połowy swojego kodu.

To tak po krótce wink.gif

I to nie jest tak, że musisz pisać coś kilka razy. W interfejsie tylko deklarujesz metody, bez ich implementacji.
Nortonek
... no własnie chodzi mi o to że interfejs jest zbędny, do niczego nie służy a już na pewno nie pomaga w wielodziedziczeniu

w końcu wiem jakie metody chcę mieć w klasie, to po co je mam deklarować w intefejsie

Jeśli piszę powiedzmy 20 klas implementujących 1 i ten sam interfejs to w tych 20 klasach muszę powielić 20 razy zadeklarowane metody, to raczej coś nie tak,

czemu od razu nie pisać sobie 20 klas dziedziczących po 1 klasie z tymi netodami, nie szybciej i nie prościej tak ?

Nie mogę po prostu zrozumieć idei przypisanej do interfejsu, jeśli hodzi o zmniejszenie ilości kodu i przyspieszenie pisania, to interfejs jest dla mnie tego zaprzeczeniem,

czy chodzi w nim tylko o czytelność i przekaz informacji ?
PrinceOfPersia
Cytat
interfejs A ma 300 metod, interfejs B ma 300 metod, interfejs C ma 300 metod, interfejs D ma 300 metod

jak napisał przedmówca - 300 metod to stanowczo za dużo na jedną klasę czy interfejs. Może 3 metody, może 5, 10, może 15...

Cytat
niby służą one do wielodziedziczenia (dla mnie oznacza to oszczędność czasu i mniej kodu)

Do wielodziedziczenia to służą inne mechanizmy. Interfejsy są bardziej jak "protokoły" do komunikacji między obiektami. Nie mają oszczędzać kodu, bo w ogóle nie definiują kodu, a jedynie nazwy metod, rodzaje argumentów i typ zwracanej wartości.

EDIT: i to jest ich celem. USTANDARDYZOWANIE. Zapewnienie, że obiekty będą się zachowywać zgodnie z interfejsem.

Cytat
Nie mogę po prostu zrozumieć idei przypisanej do interfejsu, jeśli hodzi o zmniejszenie ilości kodu i przyspieszenie pisania, to interfejs jest dla mnie tego zaprzeczeniem,

no to weź taki przypadek -- fikcyjna biblioteka SuperCaptcha2000 pozwala na skustomizowanie tego w jaki sposób ma być rysowana captcha. W tym celu definiuje interfejs ICaptchaCanvas. Żeby go użyć, musisz odziedziczyć z niego i zaimplementować metody drawLetter, drawBackground.

biblioteka SuperCaptcha później najpierw wywoła twoją metodę drawBackground, żeby narysować tgło, a później będzie wywoływała twoją metodę drawLetter dla każdej litery w słowie.

nie ma tu multidziedziczenia (nie musi być), nie ma tu 300 metod, a jedynie 2. Ale jest korzyść. Bo biblioteka SuperCaptcha2000 dokładnie wie, którą metodę wywołać z jakimi argumentami.

Bez interfejsów/"protokołu" ty byś sobie nazwał metodę po polsku rysujLitere a kolejność argumentów sobie byś zmienił, i biblioteka SuperCaptcha2000 nie miałaby pojęcia jak wywołać twoją funkcję do kustomizowania captcha.

I do tego się tego mniej więcej używa.
CuteOne
Prosty przykład

  1. interface A {
  2. public function zrob(Entites\Robota $a, array $b);
  3. }
  4.  
  5. class B implements A {
  6.  
  7. public function zrob(Entites\Robota $a, array $b) {
  8.  
  9. }
  10. }
  11.  
  12.  
  13. class C {
  14.  
  15. public function __construct(A $class) {
  16.  
  17. $class->zrob($robEntity, $tablica);
  18. }
  19. }


1. Mamy pewność, że do konstruktora zostanie przekazany obiekt, który zawiera metodę zrob()
2. Wiemy, że zawsze trzeba jej przekazać encję i tablicę
3. Klasę C nie interesuje jaki obiekt zostanie wstrzyknięty! Byle zawierał interfejs A
q3trm
Cytat(Nortonek @ 9.01.2014, 10:40:51 ) *
Jeśli piszę powiedzmy 20 klas implementujących 1 i ten sam interfejs to w tych 20 klasach muszę powielić 20 razy zadeklarowane metody, to raczej coś nie tak,

czemu od razu nie pisać sobie 20 klas dziedziczących po 1 klasie z tymi netodami, nie szybciej i nie prościej tak ?


Ja w takim przypadku stosuję abstrakcję, a interfejsy wykorzystuję, gdy jakaś klasa musi posłużyć mi do DI.

Cytat(Nortonek @ 9.01.2014, 10:40:51 ) *
Nie mogę po prostu zrozumieć idei przypisanej do interfejsu, jeśli hodzi o zmniejszenie ilości kodu i przyspieszenie pisania, to interfejs jest dla mnie tego zaprzeczeniem,

czy chodzi w nim tylko o czytelność i przekaz informacji ?

Według mnie bardziej o utrzymanie spójności między komponentami systemu, tak jak sowiq napisał.
Crozin
Czy PHP mógłby działać w ogóle bez interfejsów? Tak, mógłby, ponieważ język ten działa w nieco inny sposób, niż jakaś Java czy C#, gdzie są one niezbędne.
Po co więc interfejsy? Ponieważ porządkują kod, wprowadzają pewne wymuszenia i ograniczenia oraz dodają nieco statyczności do pisanego kodu, a im bardziej statyczny kod tym więcej narzędzi jest wstanie na nim operować.

Sporo jest też w Google: IDD
sowiq
Cytat(Nortonek @ 9.01.2014, 10:40:51 ) *
w końcu wiem jakie metody chcę mieć w klasie, to po co je mam deklarować w intefejsie

Ty może i wiesz. Ale inny programista już niekoniecznie. Masz rację, że w małych projektach, pisanych przez tydzień przez jedną osobę i dalej nierozwijanych, nie ma sensu bawić się w bardziej rozbudowane OOP, bo jest to tylko dodawanie sobie roboty. Ale sprawa ma się zupełnie inaczej w przypadku większych aplikacji, nad którymi pracuje kilku programistów jednocześnie.

Zauważ, że języki programowania wcale nie dążą do zmniejszenia liczby linijek kodu. Jest wręcz przeciwnie - dąży się do standaryzacji i pisania (najczęściej dłuższego) kodu, którego części będzie można wykorzystać ponownie w innych projektach. Gdyby tak nie było, to zapewne dalej pisalibyśmy strukturalnie smile.gif

Załóżmy, że jakiś framework pozwala na podpięcie własnej biblioteki do obsługi bazy danych. Według Ciebie prościej będzie przebijać się przez dokumentację (która pewnie nie zawsze będzie w 100% aktualizowana), czy zaimplementować udostępniony interfejs i pozwolić żeby Twoje IDE wygenerowało Ci wszystkie potrzebne metody z parametrami? (oczywiście zakładając, że metody będą dobrze ponazywane smile.gif )
em1X
Cytat(Nortonek @ 9.01.2014, 10:40:51 ) *
... no własnie chodzi mi o to że interfejs jest zbędny, do niczego nie służy a już na pewno nie pomaga w wielodziedziczeniu


Może zakończmy temat, napisałeś coś w stylu "po co mi internet, przecież mam książki", a my prowadzimy wywód, żeby Cię przekonać. Takim pisaniem zdradzasz, że kompletnie nie rozumiesz obiektowości i nigdy nie napisałeś poprawnie systemu opartego na jakichś dobrze ugruntowanych praktykach (S.O.L.I.D).

Przesiądź się może na jakiś porządniejszy framework, zf2 albo symfony2? i poczytaj o TDD i dobrych praktykach w programowaniu obiektowym. A może chcesz ćwiczenie? Napisz klasę, która będzie łączyła się z bazą danych i zwracała ostatnio dodany tam rekord, ale pod warunkiem, że nie wiesz co to za baza (plikowa/mysql/nosql/usługa REST).
prachwal
Cytat(em1X @ 11.01.2014, 09:59:24 ) *
Przesiądź się może na jakiś porządniejszy framework, zf2 albo symfony2? i poczytaj o TDD i dobrych praktykach w programowaniu obiektowym. A może chcesz ćwiczenie? Napisz klasę, która będzie łączyła się z bazą danych i zwracała ostatnio dodany tam rekord, ale pod warunkiem, że nie wiesz co to za baza (plikowa/mysql/nosql/usługa REST).


nie umiesz jeździć rowerem wsiadaj na Honde CBR
buhahahahahahahaha, ale mu życzysz
em1X
Dokładnie tak mu życzę.. a zabawa z frameworkiem nie grozi śmiercią, co najwyżej napisze kilka więcej tematów na forum, ale na pewno więcej się nauczy w krótszym czasie, niż pisanie własnego kodu i wywodów jak we wstępie, jak większość użytkowników forum, co widać po zawartości tematów.
Nortonek
Dziękuję za tą lekcję, daje mi to do myślenia, przyznaję się tak jak to zauwazył em1X że nie do końca rozumiem OOP zaczynam od pojedyńczych klas i dziedziczenia, aktualnie staram się zagłębić w pisanie MVC (codeigniter) i staram się zrozumieć ideę interfejsów, na zasadzie małych testowych projektów...

lukasz1985
Tak, interfejsy to ściema. Bo interfejs, rozumiany jako kontrakt - doskonale definiują klasy abstrakcyjne. Są wyjątki w sytuacjach o których już wiesz, bo sam sobie odpowiedziałeś na pytanie kiedy ich nie używać: wtedy, kiedy implementacja interfejsu w dwóch klasach byłaby taka sama i musiał byś kopiować kod metod wymaganych przez interfejs. A tak obecnie dzieje się bardzo często - bo ludzie nie potrafią logicznie definiować hierarchii dziedziczenia i używać kompozycji.

I nie słuchaj tego biadolenia - że jak ktoś nie rozumie interfejsów to nie potrafi programować obiektowo. Ktoś kto takimi bzdurami sypie sam jest idiotą i powinien się nauczyć programowania obiektowego, gdzie interfejsy są w ogóle nie potrzebne, a ich właściwe wykorzystanie sprowadza się najczęściej do implementacji wywołań zwrotnych w takich językach jak np. Java.
sowiq
Cytat(lukasz1985 @ 20.01.2014, 17:05:17 ) *
Ktoś kto takimi bzdurami sypie sam jest idiotą i powinien się nauczyć programowania obiektowego, gdzie interfejsy są w ogóle nie potrzebne

Nikt wcześniej w tym wątku nie napisał do nikogo, że jest idiotą. Wszyscy starają się wytłumaczyć autorowi do czego można użyć interfejsów. Więc z łaski swojej nie zapędzaj się w swoich wypowiedziach obrażając Bogu ducha winnych forumowiczów.

Oprócz interfejsów w PHP są klasy abstrakcyjne, od niedawna traitsy i inne "dziwadła". I wiesz co? Bez nich też da się pisać obiektowo i nikt nikomu na siłę ich nie wciska. Ale ja zakładam, że skoro takie rzeczy pojawiły się w PHP, to czemu ich nie używać? Już nie mówię, że robić to na siłę rozbijając niepotrzebnie swoje klasy, ale np. używając tych wbudowanych w PHP - http://www.php.net/manual/en/reserved.interfaces.php

[edit]
I jeszcze jedno.
Cytat(lukasz1985 @ 20.01.2014, 17:05:17 ) *
Bo interfejs, rozumiany jako kontrakt - doskonale definiują klasy abstrakcyjne.

Problem jest taki, że klasę abstrakcyjną możesz rozszerzyć tylko jedną, a interfejsów zaimplementować kilka jednocześnie.
vonski
Cytat(sowiq @ 20.01.2014, 17:33:40 ) *
Oprócz interfejsów w PHP są klasy abstrakcyjne, od niedawna traitsy i inne "dziwadła". I wiesz co? Bez nich też da się pisać obiektowo i nikt nikomu na siłę ich nie wciska. Ale ja zakładam, że skoro takie rzeczy pojawiły się w PHP, to czemu ich nie używać?


Dobre podsumowanie tego wątku smile.gif
Dodam jeszcze, że idąc tym tropem, że "interfejsy to ściema, bo są klasy abstrakcyjne", to można też powiedzieć, że np. private, protected i public też są zbędne bo jest var i domyślnie mogę mieć wszystko public i przecież też wszystko będzie działać. Bo będzie. Chodzi o to, że podobnie jak interfejsy, modyfikatory dostępu wymuszają pewne ograniczenia na programiście, ale jednocześnie, jeśli używane poprawnie, pozwalają uniknąć przypadkowych błędów, czy zaniedbań.

Idąc krok dalej, można powiedzieć, że OOP niewarto się uczyć, bo da się przecież pisać proceduralnie wink.gif
pyro
OOP? PHP? HTML? CSS? Bez sensu. Przecież strony można pisać w Assembly
sowiq
Dokładnie tak. Jak już napisałem wcześniej - jak piszesz aplikację przez tydzień, puszczasz ją na serwer i zapominasz na zawsze, to nie ma sensu zawracać sobie głowy bardziej zaawansowanym OOP niż dziedziczenie. Ale przy pracy w kilkuosobowym zespole czy długim rozwoju swojej aplikacji, używanie tych wszystkich "udziwnień", moim zdaniem, po prostu przyspiesza pracę, ułatwia zrozumienie kodu i (jak np. modyfikatory dostępu) chroni aplikację przed mniej doświadczonymi programistami.
Daimos
Mnie urzekł ten fragment wypowiedzi:
Cytat
w końcu wiem jakie metody chcę mieć w klasie, to po co je mam deklarować w intefejsie

Pracowałeś kiedyś w zespole? Jak będziesz pracował z Tomkiem, to mu powiesz, że mają być takie metody i koniec, ale jak będziesz pracował z:
Tomkiem, Markiem, Jankiem, Piotrkiem, Przemkiem, Stefanem, Michałem, Mariuszem i Anią smile.gif to zobaczysz, że wtedy reguła "ja to wiem, więc po co..." jest pomyłką.
To takie same podejście jak: "nie komentuje kodu, bo po co, przecież wiem co to"... chyba tego nie trzeba tłumaczyć smile.gif
lukasz1985
Fajnie się usprawiedliwiacie. Tylko te wasze teorie to można sobie za przeproszeniem "wsadzić" - konfrontując to z faktami. Takie gadanie: "nie wiem jak to poskładać, nie wiem jak mam stworzyć plugin, a to niech sobie będzie interfejs".

Już pisałem o tym w innym wątku - łamiecie zasadę pojedynczej odpowiedzialnści stosując interfejsy tak jak stosujecie i prowadzicie do duplikacji kodu. A takie gadanie: że w programowaniu zmierza się do standaryzacji też nic warte nie jest. Bo kod ma mieć czystą i przejrzystą strukture przede wszystkim poprzez to można tworzyć klasy, które można rozszerzać i nikt tutaj nie potrzebuje interfejsów!

Takie modne gadanie, powtarzacie jak małpy, i czytacie bezkrytycznie to co wam podają, a programowanie jak było tak jest kaleczone wciąż.

Jakby ktoś chciał zgłębić temat dlaczego łamie zasadę pojedynczej odpowiedzialności (kluczowej zasady dla utrzymywania zrozumiałego kodu) to zapraszam: http://devmatrix.wordpress.com/2014/01/04/...ava-interfaces/ (już ten link wrzucałem 100 razy).
pyro
@lukasz1985, radzę się zapoznać z różnicami pomiędzy klasami, a interfesjami, bo osobiście nie widzę zastosowania tego co piszesz (ani posta na blogu) do postów następujących po Twoim ostatnim. W skrócie - gadasz od rzeczy.
lukasz1985
Jak to gadam od rzeczy? Interfejs defniuje typ! Nie różni się niczym od klasy poza tym, że jest to pusty szablon klasy. Typy są fundamentalnym elementem każdego języka programowania, nie ważne czy typy są dynamiczne czy statyczne. Jeśli ktoś definiuje interfejs - definiuje typ. Jeśli ktoś definiuje dwa interfejsy definiuje dwa typy. Jeśli ktoś konstruuje klasę i implementuje w niej oba interfejsy po to aby zdefiniować jej odpowiedzialności, a nie wyłącznie w celu umożliwienia wywołań zwrotnych to wpisuje w jeden typ dwa inne typy - nadaje dwie odpowiedzialności klasie, która ma mieć jedną odpowiedzialność i łamie w ten sposób zasadę pojedynczej odpowiedzialności.

Kod to nie jest arbitralne medium ekspresji byle jakiej idei i nie jest zabawką, w której decyzje projektowe mogą być podejmowane dowolnie, a tak właśnie dzieje się od kiedy wprowadzone zostały interfejsy czy inne bajery w postaci obsługi cech czy wielodziedziczenia - to są ułomne twory, które nie wpisują się w czyste programowanie obiektowe z wielodziedziczeniem na czele.

OOP wygląda znacznie ciekawiej bez interfejsów, gdzie nawet, te jakby się wydawało banalne wywołania zwrotne nabierają wyrazistości poprzez polimorfizm. Reszta to tak naprawdę łatwy kicz, z czym miałem zaszczyt się spotkać przy okazji tworzenia pluginu dla Eclipse.
sowiq
Cytat(lukasz1985 @ 21.01.2014, 14:59:14 ) *
Interfejs defniuje typ! Nie różni się niczym od klasy poza tym, że jest to pusty szablon klasy.

Interfejs nie definiuje typu, tylko wymusza implementację określonych metod. I to jest jego cała rola. Dokładnie jak to nazwałeś w drugim zdaniu - jest to pusty szablon.

Cytat(lukasz1985 @ 21.01.2014, 14:59:14 ) *
Jeśli ktoś definiuje interfejs - definiuje typ.

Jak wyżej.

Cytat(lukasz1985 @ 21.01.2014, 14:59:14 ) *
Jeśli ktoś konstruuje klasę i implementuje w niej oba interfejsy po to aby zdefiniować jej odpowiedzialności, a nie wyłącznie w celu umożliwienia wywołań zwrotnych to wpisuje w jeden typ dwa inne typy - nadaje dwie odpowiedzialności klasie, która ma mieć jedną odpowiedzialność i łamie w ten sposób zasadę pojedynczej odpowiedzialności.

Zależy od interfejsów. Ale najczęściej nie jest to odpowiedzialność, tylko funkcjonalność. Np. implementujesz Serializable, Iterator i ArrayAccess. Po zaimplementowaniu tych interfejsów klasa jeszcze nie ma żadnej odpowiedzialności (bo nic jeszcze nie robi), ale już wiadomo jak się z nią komunikować.

Cytat(lukasz1985 @ 21.01.2014, 14:59:14 ) *
OOP wygląda znacznie ciekawiej bez interfejsów, gdzie nawet, te jakby się wydawało banalne wywołania zwrotne nabierają wyrazistości poprzez polimorfizm.

Z tym, że polimorfizm w PHP nie występuje. ( facepalmxd.gif ) A co do pierwszego zdania - programowanie bez OOP jest jeszcze bardziej ciekawe wink.gif

[edit]
Poprawiłem bzdurę.
pyro
Aha, no to przynajmniej dotarliśmy do przyczyny problemu - kiepsko u Ciebie z czytaniem ze zrozumieniem wink.gif

Cytat(lukasz1985 @ 21.01.2014, 14:59:14 ) *
Jak to gadam od rzeczy? Interfejs defniuje typ! Nie różni się niczym od klasy poza tym, że jest to pusty szablon klasy. Typy są fundamentalnym elementem każdego języka programowania, nie ważne czy typy są dynamiczne czy statyczne. Jeśli ktoś definiuje interfejs - definiuje typ. Jeśli ktoś definiuje dwa interfejsy definiuje dwa typy. Jeśli ktoś konstruuje klasę i implementuje w niej oba interfejsy po to aby zdefiniować jej odpowiedzialności, a nie wyłącznie w celu umożliwienia wywołań zwrotnych to wpisuje w jeden typ dwa inne typy - nadaje dwie odpowiedzialności klasie, która ma mieć jedną odpowiedzialność i łamie w ten sposób zasadę pojedynczej odpowiedzialności.

Kod to nie jest arbitralne medium ekspresji byle jakiej idei i nie jest zabawką, w której decyzje projektowe mogą być podejmowane dowolnie, a tak właśnie dzieje się od kiedy wprowadzone zostały interfejsy czy inne bajery w postaci obsługi cech czy wielodziedziczenia - to są ułomne twory, które nie wpisują się w czyste programowanie obiektowe z wielodziedziczeniem na czele.

OOP wygląda znacznie ciekawiej bez interfejsów, gdzie nawet, te jakby się wydawało banalne wywołania zwrotne nabierają wyrazistości poprzez polimorfizm. Reszta to tak naprawdę łatwy kicz, z czym miałem zaszczyt się spotkać przy okazji tworzenia pluginu dla Eclipse.


Co do tego się zgadzam, poprzedniemu też nie zaprzeczam (czego widocznie nie zrozumiałeś), jednak ostatni akapit tutaj to jakieś farmazony. Nie ma, że wygląda ciekawiej czy nie ciekawiej. Interfejsy to użyteczne narzędzie. Tak samo jak w np. w C jest deklarowanie typów, czego w PHP nie ma i to bardzo źle. Co jak co, ale bym chciał, żeby string pozostał stringiem, a int pozostał intem smile.gif .
lukasz1985
No wygląda to ciekawiej. Zakładam, że w Javie nie programowałeś - a jeśli to prawda - to dam Ci prosty przykład:
itsnieje interfejs "MouseListener", który implementuje się w klasie, która chce nasłuchiwać na zdarzenia myszy. W tym interfejsie są metody typu "onMouseMove" wykonywane, kiedy poruszany jest wskaźnik . Teraz - nic nie stoi na przeszkodzie, żeby zamiast interfejsu zrobić to w klasie abstrakcyjnej. Każdy klient, który chciałby nasłuchiwać na zdarzenia po prostu rozszerzałby tą klasę. Mógłby stworzyć w niej własny konstruktor w którym przyjmowałby referencję do obiektu, który chce kontrolować. Zasadniczo prowadzi to do rozbicia kodu nad dwie klasy - co jest bardzo pożądane.

Gdyby taki interfejs zaimplementowac w klasie która ma być kontrolowana - kod nie staje się bardziej modularny, a często może to prowadzić wręcz do zaciemnienia całości, gdzie metody specyficzne dla klasy mieszają się z metodami interfejsu.

@sowiq
Cóż, myślę, że jak ktoś pisze takie bzdury to nie warto odpowiadać sensownie.
freemp3
@lukasz1985, to wszystko zależy od tego co aktualnie chcesz zrobić w większości przypadków tak jak mówisz, wystarczy klasa abstrakcyjna, ale interfejsy po to zostały stworzone, żeby właśnie określać jakie metody ma mieć klasa, która go implementuje. Nie ważne co one będą robić, mogą nic nie robić, ważne żeby były. Chodzi tutaj o integralność aplikacji, żeby nie było sytuacji, w której dołączasz moduł i okazuje się, że brakuje mu metody install(). W tym momencie cała aplikacja się sypie.

W javie z tego co wiem, też można dziedziczyć tylko z jednej klasy więc to aż się prosi, żeby wykorzystać interfejs i zostawić sobie możliwość na dodanie ewentualnego dziedziczenia. Dlatego lepiej jeśli masz tylko spis metod, wykorzystać interfejs, a klasę abstrakcyjną, tam gdzie będzie miała metody, które coś robią.
lukasz1985
Klasa abstrakcyjna też może zobowiązywać do implementacji określonych metod (dlatego jest abstrakcyjna) , a co więcej może deklarować pola i metody z już obecną implementacją, w sytuacjach gdy istnieje pewność, że będą one takie same we wszystkich implementacjach.
nospor
Tak, ale klasa moze implementowac wiele interfejsow, podczas gdy dziedziczyc moze tylko z jednej klasy.

ps: i nie wyzywaj ludzi od idiotow tylko dlatego, ze maja inne zdanie niz Ty. Swoją drogą bardzo mnie (nie)ciekawi jak to ma sie do twojego ogłaszania sie jaki to z Ciebie chrzescijanin.... brrrr, tylko antyreklame chrześcijanom robisz.

edit, widze ze powielilem sowiqa
Cytat
Problem jest taki, że klasę abstrakcyjną możesz rozszerzyć tylko jedną, a interfejsów zaimplementować kilka jednocześnie.
smile.gif Tak czy siak, jesli ten argument nie przemawia do naszego "wichrzyciela" to nie rozumiem po grzyba z nim jeszcze dyskutujecie wink.gif
pyro
Czyli rozumiem, że jakbym chciał robić np. sterowniki, które dziedziczą oraz dodatkowo posiadają ten sam typ zaimplementowany w różny sposób, to... co?

Rozumiem dodatkowo, że wszystkie te frameworki i stosowanie w nich interfejsów to po prostu żenada bez względu na to, jak bardzo porządkują i ułatwiają pracę? I w ogóle nawet w Javie, na którą się powołujesz, autorzy stworzyli możliwość używania interfejsów tylko dla czystej zabawy, zwłaszcza, że jest to jeden z "najbardziej obiektowych" języków? I w ogóle Ci wszyscy programiści z wieloletnim doświadczeniem sukcesywnie je stosując to po prostu cieniasy i dzieciaki, a Ty po prostu wiesz, że ich stosowanie to zło?

Z całym szacunkiem, ale ogarnij się, bo klepiesz farmazony totalne. Powinienem napisać do @emp'a, żeby tu przyszedł i zrobił z Tobą porządek tongue.gif
lukasz1985
Widzę, że logika do was nie przemawia. Porządek? Od kiedy się zaczęły interfejsy to jest istny burdel we wszystkich API. Ja nikogo nie nazwałem idiotą. Powiedziałem według jakich kategorii należy oceniać czy ktoś jest idiotą. Poza tym, to nie ja komuś jako pierwszy zarzuciłem niekompetencje.

Mam nadzieje, że autor tego tematu ma w głowie poukładane i nie kupi tych bzdur które tutaj czytam.

Koniec tematu z mojej strony.


PS:
Cytat
Rozumiem dodatkowo, że wszystkie te frameworki i stosowanie w nich interfejsów to po prostu żenada bez względu na to, jak bardzo porządkują i ułatwiają pracę? I w ogóle nawet w Javie, na którą się powołujesz, autorzy stworzyli możliwość używania interfejsów tylko dla czystej zabawy, zwłaszcza, że jest to jeden z "najbardziej obiektowych" języków? I w ogóle Ci wszyscy programiści z wieloletnim doświadczeniem sukcesywnie je stosując to po prostu cieniasy i dzieciaki, a Ty po prostu wiesz, że ich stosowanie to zło?


To, że większość mówi to samo, nie znaczy, że jest to prawdziwe.
pyro
Cytat(lukasz1985 @ 21.01.2014, 17:22:08 ) *
Widzę, że logika do was nie przemawia. Porządek? Od kiedy się zaczęły interfejsy to jest istny burdel we wszystkich API.


To akurat wyłącznie Twoje subiektywne spotrzeżenie, bo akurat według mnie robiono kiepskie API i dobre API i teraz również robione są zarówno kiepskie jak i dobre API (tak, z interfejsami). Z tego wynika tylko tyle, że jak sam wspomniałeś obracasz się tylko wokół kiepskiego kodu i pewnie dlatego potem rozsiewasz takie glamoty na lewo i prawo.

Cytat(lukasz1985 @ 21.01.2014, 17:22:08 ) *
Ja nikogo nie nazwałem idiotą. Powiedziałem według jakich kategorii należy oceniać czy ktoś jest idiotą. Poza tym, to nie ja komuś jako pierwszy zarzuciłem niekompetencje.


Radzę przypomnieć, że nie otrzymałeś od nikogo daru nadawania kategorii, według których selekcjonuje się idiotów. Nie Ty jesteś od tego.

Cytat(lukasz1985 @ 21.01.2014, 17:22:08 ) *
To, że większość mówi to samo, nie znaczy, że jest to prawdziwe.


To akurat chyba jedyna sensowna rzecz, jaką napisałeś w tym temacie. Tylko, że Ty w żaden sposób nie udowodniłeś tego, że tutaj ta większość się myli. Wręcz przeciwnie. Inni tłumaczą Ci dlaczego coś ma sens i jest tak, a nie inaczej, a Ty jedynie się uparłeś na jakąś dziwną tezę i nie potrafisz jej w żaden sensowny sposób uargumentować.

Mało tego. Poklikałem sobie po linkach w stopce w nadzei, że dojrzę tam jakiś kod, algorytm, rozwiązanie jakiegoś problemu w ciekawy sposób i rzeczywiście czegoś fajnego można się będzie dowiedzieć na poparcie Twoich tez (bo w temacie oczywiście nie potrafiłeś tego zrobić), ale to co zobaczyłem mnie zupełnie rozbroiło. Tragedia totalna. Bez złośliwości, ale widziałem sporo ludzi, którzy na tym forum do działu Oceny wrzucali swoje pierwsze w życiu stronki, które jakościowo były o niebo, nieporównywalnie lepsze niż to co tam ujrzałem. Z całym szacunkiem, ale raczej nigdy nie będziesz w stanie zaprzeczyć tezie, że przychodząc z takim czymś nie masz możliwości sprzeczania się z bardziej doświadczonymi użytkownikami.

Pozdrawiam i radzę poprzestać na:

Cytat(lukasz1985 @ 21.01.2014, 17:22:08 ) *
Koniec tematu z mojej strony.
irmidjusz
Od początku tego tematu wiedziałem, żeby się nie udzielać, bo to klasyczny troll, i miałem rację smile.gif Wreszcie na koniec mogę jeszcze dodać swoje wytłumaczenie (może dotrze). Zbiór uwag dla lukasz1985:

Podany przykład nieprawidłowego używania interfejsów w Javie jest... przykładem nieprawidłowego używania interfejsów w Javie. Tylko tyle. Nie jest to dowód na to, że interfejsy są złe. W ramach ćwiczeń (jeśli chcesz cokolwiek zrozumieć) zaprojektuj klasę implementującą dwa interfejsy tak, żeby zasada SRP nie była naruszona.

Dziedziczenie klasy abstrakcyjnej różni się znacząco pod względem koncepcyjnym od implementacji interfejsu; ale różni się także technicznymi możliwościami oferowanymi przez język programowania - czyli tym, co możesz lub nie możesz zrobić.

Implementacja interfejsów nie jest wielodziedziczeniem i nie zastępuje wielodziedziczenia. W implementacji interfejsów nie ma dziedziczenia w ogóle. Dziedziczyć można tylko implementację. Dlatego też dziedziczenie po klasie abstrakcyjnej (lub nieabstrakcyjnej) jest czymś zupełnie innym od implementacji interfejsu.

Definiując interfejs, definiujesz typ z jego możliwymi zachowaniami. Tworząc klasę abstrakcyjną, tworzysz częściową implementację.

Używając tylko klas jedyne co masz do dyspozycji, to dziedziczenie innych klas, czyli implementacji (plus kompozycję rzecz jasna, ale to nie jest w temacie). Stosowanie interfejsów oferuje możliwość tworzenia całkowicie niezależnych od siebie implementacji typów zdefiniowanych przez interfejsy.

Mógłbyś pomyśleć, że można zastąpić interfejsy klasami abstrakcyjnymi, które deklarują tylko i wyłącznie publiczne abstrakcyjne metody, ale tak nie jest. Otóż po pierwsze, tak używana klasa abstrakcyjna już z definicji staje się tożsama logicznie z interfejsem (jest od niego nierozróżnialna dla klienta używającego klasy konkretnej). Po drugie, w językach bez wielodziedziczenia i bez interfejsów, będziesz skazany na tworzenie niezgodnych z OOP, błędnie zdefiniowanych i nadmiernie rozbudowanych hierarchii dziedziczenia, bądź znaczną duplikację kodu.
lukasz1985
Cytat
Nie jest to dowód na to, że interfejsy są złe. W ramach ćwiczeń (jeśli chcesz cokolwiek zrozumieć) zaprojektuj klasę implementującą dwa interfejsy tak, żeby zasada SRP nie była naruszona.


Nie powiedziałem nigdzie, że są złe, powiedziałem, że są nadużywane i błędnie wykorzystywane. bo:

Cytat
zaprojektuj klasę implementującą dwa interfejsy tak, żeby zasada SRP nie była naruszona.


Świetnie - i sprowadzi się (jeśli zostało wykonane we właściwy sposócool.gif to do implementacji funkcji wykonujących wywołania zwrotne, o czym już pisałem


Cytat
Po drugie, w językach bez wielodziedziczenia i bez interfejsów, będziesz skazany na tworzenie niezgodnych z OOP, błędnie zdefiniowanych i nadmiernie rozbudowanych hierarchii dziedziczenia, bądź znaczną duplikację kodu.


Świetnie, tylko teraz powiedz mi jak interfejsy zapobiegają duplikacji kodu? Aha, misiu kolorowy, chciałem Ci powiedzieć, że w każdym języku OOP w którym wielodziedziczenia nie ma można je łatwiutko zasymulować poprzez subtelny sposób kompozycji, o którym więcej Ci pisał nie będę bo jeśli nie przyszedłeś tutaj tylko trolować to zainteresujesz się tym osobiście.


pyro
Cytat(lukasz1985 @ 22.01.2014, 10:33:34 ) *
Nie powiedziałem nigdzie, że są złe, powiedziałem, że są nadużywane i błędnie wykorzystywane. bo:


Ręce opadają. To się zdecyduj w końcu czy Twoja wiedza jest spora w brakach, czy po prostu Twoja umiejętność czytania ze zrozumieniem leży wyjątkowo płasko i kwiczy. KTO? GDZIE napisał, że nadużywanie i błędne wykorzystywanie interfejsów jest prawidłowe? Albo chociaż podał jakiś fragment kodu, który do zarzutów klarownie pasuje? Ja jakoś nie widzę. Może przeoczyłem? W takim razie ZACYTUJ.

Pomijam już fakt nazwanie mnie na PW materialistą, bo śmiałem ocenić Twoją pracę po wyglądzie, a ponieważ zablokowałeś możliwość odpowiedzi Ci tam, w takim razie odpowiadam Ci tutaj: Nie oceniłem Twojej pracy po wyglądzie, oceniłem ją po wyglądzie ORAZ kodzie. I jak nie po tych dwóch rzeczach mam ją oceniać, to niby po czym, skoro strony www składają się wyłącznie z tych dwóch rzeczy?questionmark.gifexclamation.gif!

lukasz1985
Dobry jesteś, dużo zobaczyłeś - troche HTML'a i szczątki JS (o ile w ogóle chciało Ci się w JS zaglądać). Proszę, nie wypowiadaj się już na moim punkcie, na tym forum tylko rób to w PW (do czego i tak już nie będziesz miał okazji).

Co do interfejsów przykład masz w moim artykule. Przykład błędu który jest powielany w niemalże kazdym framwerku PHP i każdej bibliotece Javy a nawet w jej standardowej bibliotece, np z kolekcjami.

Jeśli nie potrafisz tego przeczytać ze zrozumieniem i pojąć prostej zasady, że deklarując 3 interfejsy deklarujesz 3 rodzaje odpowiedzialności i jeśli 1 z tych interfejsów jest wspólny dla 2 klas to dzielą one jedną odpowiedzialność i w ten sposób łamana jest zasada jednej odpowiedzialności to nie sądzę żabyś był w stanie pojąć, że jedynym słusznym rozwiązaniem jest użycie interfejsów w roli mechanizmu umożliwiającego wykonywanie wywołań zwrotnych.

O tym wszystkim pisałem już dziesiątki razy i już nie będę tego kolejny raz powtarzał.
pyro
Ktoś już odpowiedział na te bzdety:

Cytat(irmidjusz @ 21.01.2014, 20:31:12 ) *
Podany przykład nieprawidłowego używania interfejsów w Javie jest... przykładem nieprawidłowego używania interfejsów w Javie. Tylko tyle. Nie jest to dowód na to, że interfejsy są złe.


Ja niestety popełniłem popełniłem błąd, którego @irmidjusz nie popłenił i podjąłem się dalszej dyskusji. Niestety do Ciebie nic nie dociera, nieważne jak solidnie ktoś obala farmazony, które siejesz na lewo i prawo. Żyjesz w jakimś swoim wyimaginowanym świecie, gdzie dla Ciebie liczy się to co sobie wymyśliłeś, a nie jakie są fakty.

Z mojej strony EOT. Natomiast jeśli jesteś trollem to muszę przyznać, że na najwyższym poziomie.
nospor
Dobra, zamkne juz ten temat, ktory raczej zostal juz wyczerpany. Jesli ktos sie nie zgadza, i chce cos konkretnego dodac, zapraszam na PW.

ps: @lukasz1985 Ty weż nie walaj durnia, i jak do kogos piszesz na PW, prowokujac tym samym rozmowe, to nie blokuj od razu temu komus mozliwosci odpowiedzenia. Zachowujesz sie gorzej jak dziecko w przedszkolu :/
phpion
Cytat(lukasz1985 @ 21.01.2014, 17:22:08 ) *
Koniec tematu z mojej strony.

Cytat(pyro @ 22.01.2014, 11:15:07 ) *
Z mojej strony EOT.


I tego się trzymajmy, sugeruję koniec dalszych przepychanek.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.