Sens |
Sens |
12.07.2016, 20:55:31
Post
#1
|
|
Grupa: Zarejestrowani Postów: 72 Pomógł: 11 Dołączył: 8.05.2016 Ostrzeżenie: (0%) |
Witam.
Nie rozumiem paru rzeczy w programowaniu obiektowym, mianowicie sensu interfejsów i abstrakcji. Przecież taki interfejs w ogóle jest niepotrzebny i tylko zwiększa (nieznacznie) rozmiar naszego pliku, albowiem on tylko wymusza zdefiniowanie jakiejś metody. Ogólnie tą metodę możemy zdefiniować bez żadnego interfejsu - efekt ten sam.
Abstrakcji też nie rozumiem. Przecież ów deklaracja jest absolutnie niepotrzebna; można to zrobić w klasie, która coś dziedziczy.
Ogólnie nie widzę sensu w użytku tego - jest to używane tylko do debugowania albo przejrzystości czy jak? Bo ogółem nie ma to innego sensu raczej. |
|
|
12.07.2016, 22:53:14
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 240 Pomógł: 278 Dołączył: 11.03.2008 Ostrzeżenie: (0%) |
http://forum.php.pl/index.php?showtopic=111328
https://forum.4programmers.net/Java/221811-...wie_je_stosowac -------------------- |
|
|
13.07.2016, 12:17:09
Post
#3
|
|
Grupa: Zarejestrowani Postów: 6 365 Pomógł: 1114 Dołączył: 30.08.2006 Ostrzeżenie: (0%) |
Po pierwsze stosuje się PSR-4 http://www.php-fig.org/psr/psr-4/ i interface, trait oraz wszystkie klasy powinny być definiowane w osobnych plikach.
Po drugie implementacja interface w klasie wymusza własną implementację danej metody czyli w twoim pierwszym przykładzie intf::example(). Strukturyzuje też kod. Załóżmy gdybyś miał: UserStorageInterface.php
DbUserStorage.php
ArrayUserStorage.php
ExternalServiceUserStorage.php - czyli dane pochodzące z obcych serwisów pobierane przez API
W każdej z klas musiałbyś zaimplementować pobieranie danych o użytkownikach. Metoda na zrobienie tego byłaby różna w zależności od klasy (wybranie z bazy, pobranie z tablicy albo z zewnątrz) ale miałbyś pewność że klasy te posiadają daną metodę. I teraz jeszcze ważniejsze:
Oraz co za tym idzie rzutowanie: UserRepository.php
Dzięki temu do klasy UserRepository możesz przekazać dowolny obiekt który implementuje UserStorageInterface. Jakiś czas temu pisałem też o klasach gdzie masz wytłumaczoną abstrakcję. Ten post edytował viking 13.07.2016, 12:26:45 -------------------- |
|
|
13.07.2016, 19:21:51
Post
#4
|
|
Grupa: Zarejestrowani Postów: 531 Pomógł: 55 Dołączył: 3.01.2016 Skąd: Łowicz Ostrzeżenie: (0%) |
Na początku programowania OO też nie rozumiałem w ogóle co to interface i abstract class.
Aktualnie rozumiem to w ten sposób że: Interfejs i Klasa Abstrakcyjna jest to narzucony przez programistę sposób nazewnictwa metod, taka instrukcja dla innych programistów, lub dla siebie samego. Interfejs zawiera jedynie deklarację metod, klasa abstrakcyjna może zawierać dodatkowo działające abstrakcyjne metody. Pisząc swoje proste aplikacje/frameworki nie stosowałem nigdy interfejsów, natomiast bardzo często pisałem klasy abstrakcyjne, może za często. -------------------- Szukam zleceń Symfony, Laravel, Back-End, Front-End, PHP, MySQL ...
|
|
|
13.07.2016, 19:30:03
Post
#5
|
|
Grupa: Moderatorzy Postów: 6 070 Pomógł: 860 Dołączył: 10.12.2003 Skąd: Dąbrowa Górnicza |
Z tymi "działającymi abstrakcyjnymi metodami" to się chyba trochę zagalopowałeś. W skrócie interfejs tym różni się od klasy abstrakcyjnej, że definiuje co robi dana klasa, a nie jak.
|
|
|
14.07.2016, 07:15:38
Post
#6
|
|
Grupa: Zarejestrowani Postów: 148 Pomógł: 14 Dołączył: 23.02.2013 Ostrzeżenie: (0%) |
Interfejs jest po to abyś mógł podpowiedzieć sobie lub innemu programiście czego oczekujesz od danego obiektu klasy, co powinien on umieć zrobić. Gdy np. przyjmujesz obiekt poprzez dependency injection, jak zostało to pokazane wyżej w UserRepository, to możesz się spodziewać że przekazany Ci obiekt będzie robił to co interfejs UserStorageInterface mu każe. Oznacza to że spokojnie w innym miejscu możesz wywoływać na danym obiekcie metody zaimplementowane z interfejsu UserStorageInterface bez obaw że ich tam nie ma i że dostaniesz fatal error podczas wykonywania kodu. Gdy natomiast jesteś zainteresowany tym by skorzystać z UserRepository to od razu wiesz jakie metody powinieneś zaimplementować w swoich obiektach.
-------------------- |
|
|
14.07.2016, 18:25:43
Post
#7
|
|
Grupa: Zarejestrowani Postów: 3 032 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%) |
Interfejsy są rozwiązaniem wielodziedziczenia, które znane jest z c++, wiec jak potrzebujesz przykładowo 2 klasy które będą miały takie same metody, ale ich działanie będzie inne to najłatwiej zrobić dla nich interfejs i wtedy masz uporządkowana strukturę, a klasa abstrakcyjna to częściowa cześć wspólna dlatego nie da sie stworzyć obiektu takiej klasy. W php mamy jeszcze cechy
|
|
|
15.07.2016, 07:21:00
Post
#8
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) |
@com to co napisałeś to nie jest wielodziedziczenie Wielodziedziczenie jest wtedy gdy klasa dziedziczy po kilku klasach. Namiastką tego są Traits.
Przykład z moich ostatnich wojów. Mam sobie Commands (kilka różnych). Tworzę sobie rozszerzoną wersję każdego. Siłą rzeczy robię extends dla każdego z odpowiedniego Commands. Jednak moje commands mają wspólne metody. I tu by się przydało wielodziedziczenie żeby wypchnąć te metody do innego wspólnego Command, ale nie da się. I tu wchodzi Traits. |
|
|
15.07.2016, 20:39:56
Post
#9
|
|
Grupa: Zarejestrowani Postów: 72 Pomógł: 11 Dołączył: 8.05.2016 Ostrzeżenie: (0%) |
Traitsy jak najbardziej mają sens, zmniejszają rozmiar pliku + nie musisz kopiować tych samych rzeczy do różnych klas. Po prostu mniej pracy.
Hmm, no cóż, może kiedyś postanowię jednak używać te interfejsy i abstrakcje. Przynajmniej ujrzałem jakieś możliwe zastosowanie, dziękuję. A tak poza tym czemu trzeba dołączać wszystkie klasy w oddzielnych plikach? Osobiście uważam, że wolę mieć deklaracje klas w innym pliku niż ten, w którym będą mi one potrzebne - mniej scrollowania itp., ale czemu każda klasa w oddzielnym pliku? Ma to w ogóle jakiekolwiek znaczenie? |
|
|
15.07.2016, 22:36:05
Post
#10
|
|
Grupa: Zarejestrowani Postów: 332 Pomógł: 10 Dołączył: 13.03.2014 Skąd: Bydgoszcz Ostrzeżenie: (0%) |
Traitsy jak najbardziej mają sens, zmniejszają rozmiar pliku + nie musisz kopiować tych samych rzeczy do różnych klas. Po prostu mniej pracy. Hmm, no cóż, może kiedyś postanowię jednak używać te interfejsy i abstrakcje. Przynajmniej ujrzałem jakieś możliwe zastosowanie, dziękuję. A tak poza tym czemu trzeba dołączać wszystkie klasy w oddzielnych plikach? Osobiście uważam, że wolę mieć deklaracje klas w innym pliku niż ten, w którym będą mi one potrzebne - mniej scrollowania itp., ale czemu każda klasa w oddzielnym pliku? Ma to w ogóle jakiekolwiek znaczenie? Nie trzeba ale ułatwia to czytanie kodu. Łatwiej jest szukać metody getUserId z klasu Users która jest w pliku users.class.php niż w pliku allClasses.php |
|
|
16.07.2016, 07:08:18
Post
#11
|
|
Grupa: Zarejestrowani Postów: 6 365 Pomógł: 1114 Dołączył: 30.08.2006 Ostrzeżenie: (0%) |
Robi się tak ze względu na autoloader który automatycznie mapuje nazwę pliku na nazwę klasy. I jest dużo bardziej czytelne.
A juz na pewno nie używa się teraz.class.php. to było za czasow początków PHP 5. Ten post edytował viking 16.07.2016, 07:09:33 -------------------- |
|
|
16.07.2016, 15:23:18
Post
#12
|
|
Grupa: Zarejestrowani Postów: 3 032 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%) |
Pyton_000 ja wiem co to wielodziedziczenie, może źle się wyraziłem, w cpp było wielodziedziczenie, którego ludzie strasznie nie lubili w takiej postaci w jakiej było, stad wzrosła popularność interfejsów i klas abstrakcyjnych, które pozwalały w takich językach jak np java stworzyć namiastkę tego co było w cpp ale innym sposobem.
No ale jak masz klasę Foo, która będzie abstrakcyjna i cześć wspólna zaimplementujesz a resztę pozostawisz ew nadpiszesz w pochodnej, to da się nie używać traintów przykład https://github.com/zendframework/zend-diactoros to dało sie napisac znacznie prościej bez traitów, które bardzo często zaciemniają tylko kod |
|
|
21.07.2016, 15:55:27
Post
#13
|
|
Grupa: Zarejestrowani Postów: 7 Pomógł: 0 Dołączył: 21.07.2016 Ostrzeżenie: (0%) |
Hej @IAmBoskiM widze, że jestes w dość podobnej sytuacji co ja Tyle, że ja już zrozumiałem co to są interfejsy/abstrakcje i po co
Generalnie masz bardzo dużo racji: one są niemal niepotrzebne w starszych wersjach PHP. W najnowszej 7.0 już jest lepiej ale nadal niedoskonale. Ich znaczenie zrozumiałem dopiero gdy poczytałem kilka książek o programowaniu gdzie opisane są jezyki naprawdę obiektowe W dobrym języku obiektowym deklarujac jakas funkcje lub metode mozna wymusic by podany argument byl danego typu: byl daną klasą lub implementowal dany interfejs lub rozszerzal daną klase abstrakcyjną. Spojrz na ten kod:
Wiec jest sobie jakis czlowiek, pan domu, ktory moze karmic swoje zwierzeta. I teraz kod ktory uzyjemy do karmienia zwierzecia (kota):
Wszystko jest pieknie, ale nie masz zadnej kontroli nad tym czy zwierze, ktore probujesz nakarmic je mięso. OK, wlasnie sobie myslisz: jak to nie maz? Przeciez widze wyraznie co napisalem. Utworzylem kota z jakiejs tam klasy i go karmie miesem. To jest zupelna prawda pod warunkiem, ze to ty jestes autorem klasy Kot(), ktorej specjalnie tu nie napisalem i wewntarz tego kota sa napisales metode je(), ktora wywoluje metode gryzie(), potem trawi() i dokladniej trawi_mieso() (zakladamy ze zwierz. roslinozerne beda mialy zamiast tego trawi_rosliny()) i tak dalej. Jednak w warunkach naturalnych nad kodem pracuje sie w wiele osob. To ktos inny dostarczy klase Kot. Mozesz oczywiscie przejrzec jak ta klasa w srodku wyglada i jesli cos jest nie tak odeslac ten kod do wspolpracownika by go poprawil. Ale jesli pracujecie nad funkcją obslugującą Zoo zajmie ci to wieki zanim przejrzysz tak wszystkie zwierzeta, prawda? I teraz pojawia sie polsrodek w postaci interfejsu. Tworzysz interfejs Zwierzeta_Miesozerne w ktorym definiujesz co taki zwierzak musi umiec:
I pieknie. teraz tylko mowisz wszystkim wspolracownikom, twórcom zwierząt by ich zwierzeta implementowaly ten interfejs. Zaczynasz juz lapac? Czekaj, to jeszcze nie wszystko oczywiscie nadal musisz przegladac dostarczony kod czy on implementuje ten interfejs, prawda? O wiele mniej roboty, ale nadal jest robota. Tu z pomocą przychodzi ostatnia wlasciwosc takich kontrukcji: wymuszanie typu parametrow. Przepisz swoj kod z samego poczatku mojego wyjasnienia tak by linijka:
wygladala:
Takie cos wymusza by przekazane zwierze implementowalo dany interfejs. Jesli tak nie bedzie, PHP zwroci blad typu i po prostu calosc nie bedzie dzialac. Zatem juz nie musisz kodu przegladac: jesli programista cie nie poslucha, kod zwyczajnie nie bedzie dzialac. Podsumowujac: tak jak ci to wyzej napisano, interfejsy i abstrakcje to jest rodzaj "umowy" w kodzie, umowy miedzy programistami tworzącymi różne fragmenty kodu, umowy dzieki ktorej zaden programista nie musi zagladac do srodka kodu stworzonego przez innego programiste. Ten post edytował kkarpieszuk 21.07.2016, 15:59:34 |
|
|
22.07.2016, 17:29:58
Post
#14
|
|
Grupa: Zarejestrowani Postów: 3 032 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%) |
kkarpieszuk wszystko fajnie, ale uargumentuj co masz na myśli mówiąc, że "one są niemal niepotrzebne w starszych wersjach PHP". Sorry ale co takiego 7 zmieniła w stosunku do 5?
Ok możemy zwracać konkretny typ i dodali obsługę skalarów, ale to niczego tutaj nie zmieniło. |
|
|
22.07.2016, 19:57:17
Post
#15
|
|
Grupa: Zarejestrowani Postów: 7 Pomógł: 0 Dołączył: 21.07.2016 Ostrzeżenie: (0%) |
@com w trakcie pisania doszedlem do tego samego, ale juz nie wykasowalem
w 5 brakuje mi jeszcze deklaracji zwracanych danych, ale ja juz siedze na 7 wiec problemow nie mam |
|
|
23.07.2016, 11:17:47
Post
#16
|
|
Grupa: Zarejestrowani Postów: 515 Pomógł: 63 Dołączył: 27.08.2012 Ostrzeżenie: (0%) |
Do autora tematu
Pytasz o znaczenie rzeczy, na temat których powstalo wiele ksiazek. Nie oczekuj ze ktokolwiek tutaj wyjaśni Ci sens. Zamiast ciągnąc temat, polecam Ci książke PHP Objects, Patterns and Practice edycje 3. Jak ja przeczytasz to zrozumiesz ze na ten moment nie masz bladego pojecia o programowaniu obiektowym. Zrozumiesz ze oop to prawdziwa sztuka, a nie tępe napisanie kilku klas - co kazdy potrafi. Pózniej wrocisz pamiecia do tego postu i sam z siebie bedziesz sie smial. Jesli ludzie kierowali by sie zasadą ,,po co'' to do niczego bysmy nie doszli. Jesli nadal bedziesz szedl na latwizne to nigdy nie bedziesz dobrym programista - w sumie z korzyscia dla mnie bo im mniej konkurencji tym ja wiecej zarobie ; ) |
|
|
Wersja Lo-Fi | Aktualny czas: 19.04.2024 - 04:01 |