Dlaczego zwracać obiekt zamiast tablicy?

84

Dużo pracuję w WordPressie i zauważyłem, że znacznie więcej funkcji zwraca obiekty niż tablice. Wyniki bazy danych są zwracane jako obiekty, chyba że wyraźnie poprosisz o tablicę. Błędy są zwracane jako obiekty. Poza WordPress, większość interfejsów API udostępnia obiekt zamiast tablicy.

Moje pytanie brzmi: dlaczego używają obiektów zamiast tablic? W większości nie ma to większego znaczenia, ale w niektórych przypadkach przedmioty trudniej jest nie tylko przetworzyć, ale także owinąć głowę. Czy istnieje powód, dla którego warto używać obiektu?

Jestem samoukiem programistą PHP. Mam dyplom ze sztuk wyzwolonych. Więc wybacz mi, jeśli brakuje mi podstawowego aspektu informatyki. ;)

Dennis
źródło
5
Jestem tego ciekawy ze względu na wady obiektów, takie jak brak możliwości korzystania z nich count()lub array_*()funkcji na nich (przynajmniej w odniesieniu do przechowywania / zwracania danych klucza => wartości). Wydaje się, że nikt o tym nie wspomina, czy czegoś mi brakuje?
Wesley Murch
8
Obiekty mogą być policzalne i iterowalne poprzez implementację interfejsów Countable lub Iterator. Sprawdź również php.net/manual/en/book.spl.php .
simshaun
Jeśli masz zainstalowany SPL i implementujesz interfejs policzalny dla swojej klasy obiektów, możesz wywołać count()obiekt.
Nikt nie wyprowadza się z SE
2
W wielu przypadkach tablica nie ma nawet sensu, ponieważ nie zwraca się kolekcji obiektów lub kolekcji, której nie można łatwo emulować za pomocą tablic. Kiedy masz po prostu sekwencję innych wartości i nie ma skojarzonej dodatkowej semantyki, na miłość boską zwróć tablicę - ale przekonasz się, że rzadko tak jest.
8
@delnan i inni: Zauważ, że @Dennis mówi o tablicach asocjacyjnych (aka. słowniki, aka. mapy), a nie o tablicach normalnych (integer-index). Są to podstawowa funkcja PHP i służą mniej więcej temu samemu celowi, co klasy dynamiczne ( stdClass). Nie jestem pewien, czy na to pytanie odpowiada inna odpowiedź niż „Ponieważ programiści pracujący głównie w OOP wolą semantykę używania obiektów”
BlueRaja - Danny Pflughoeft

Odpowiedzi:

62

Oto powody, dla których ogólnie preferuję obiekty:

  • Obiekty zawierają nie tylko dane, ale także funkcjonalność.
  • Obiekty mają (w większości przypadków) predefiniowaną strukturę. Jest to bardzo przydatne przy projektowaniu interfejsu API. Ponadto możesz ustawić właściwości jako publiczne, chronione lub prywatne.
  • obiekty lepiej pasują do programowania obiektowego.
  • W większości IDE automatyczne uzupełnianie działa tylko dla obiektów.

Oto coś do przeczytania:

Sascha Galley
źródło
3
pierwsze łącze wydaje się nie być dobre? Mam na myśli to, że działa, ale przenosi do innego tematu
Geo
24

Prawdopodobnie nie jest to coś, co będziesz głęboko rozumieć, dopóki nie będziesz pracować nad dużym projektem oprogramowania przez kilka lat. Wiele nowych kierunków informatycznych udzieli odpowiedzi za pomocą wszystkich właściwych słów (hermetyzacja, funkcjonalność z danymi i łatwość konserwacji), ale niewielu naprawdę zrozumie, dlaczego warto mieć to wszystko.

Przeanalizujmy kilka przykładów.

  • Jeśli zwracane są tablice, wówczas albo wszystkie wartości muszą zostać obliczone z góry, albo trzeba zwrócić wiele małych wartości, z których można zbudować bardziej złożone wartości.

Pomyśl o metodzie API, która zwraca listę postów WordPress. Wszystkie te posty mają autorów, autorzy mają nazwiska, adresy e-mail, a może nawet profile z ich biografiami.

Jeśli zwracasz wszystkie posty w tablicy, musisz ograniczyć się do zwracania tablicy identyfikatorów postów:

[233, 41, 204, 111]

lub zwraca ogromną tablicę, która wygląda mniej więcej tak:

[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': '[email protected]', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]

Pierwszy przypadek zwracania listy identyfikatorów nie jest dla Ciebie zbyt pomocny, ponieważ wtedy musisz wykonać wywołanie API dla każdego identyfikatora, aby uzyskać informacje o tym poście.

Drugi przypadek będzie wymagał o wiele więcej informacji niż potrzebujesz przez 90% czasu i będzie wykonywał znacznie więcej pracy (zwłaszcza jeśli którekolwiek z tych pól jest bardzo skomplikowane).

Z drugiej strony obiekt może zapewnić dostęp do wszystkich potrzebnych informacji, ale jeszcze ich nie pobrał. Określanie wartości pól można wykonać leniwie (to znaczy, gdy wartość jest potrzebna, a nie wcześniej) podczas korzystania z obiektu.

  • Tablice udostępniają więcej danych i możliwości niż zamierzano

Wróć do przykładu zwracanej masowej tablicy. Teraz ktoś może prawdopodobnie zbudować aplikację, która iteruje po każdej wartości w tablicy postów i drukuje ją. Jeśli API zostanie zaktualizowane, aby dodać tylko jeden dodatkowy element do tej tablicy postów, kod aplikacji ulegnie awarii, ponieważ będzie drukować nowe pole, którego prawdopodobnie nie powinien. Jeśli kolejność elementów w tablicy wiadomości zwróconej przez interfejs API ulegnie zmianie, spowoduje to również uszkodzenie kodu aplikacji. Zatem zwrócenie tablicy tworzy wszelkiego rodzaju możliwe zależności, których obiekt by nie utworzył.

  • Funkcjonalność

Obiekt może zawierać w sobie informacje, które pozwolą mu zapewnić użyteczną funkcjonalność. Na przykład obiekt postu może być wystarczająco inteligentny, aby zwrócić poprzednie lub następne posty. Tablica nigdy nie mogłaby tego za Ciebie zrobić.

  • Elastyczność

Wszystkie wymienione wyżej zalety obiektów pomagają stworzyć bardziej elastyczny system.

Matt Crinklaw-Vogt
źródło
10

Moje pytanie brzmi: dlaczego używają obiektów zamiast tablic?

Prawdopodobnie z dwóch powodów:

  • WordPress jest dość stary
  • tablice są szybsze i w większości przypadków zajmują mniej pamięci
  • łatwiejsze do serializacji

Czy istnieje powód, dla którego warto używać obiektu?

Nie. Ale jest wiele innych dobrych powodów, na przykład:

  • możesz przechowywać logikę w obiektach (metody, domknięcia itp.)
  • możesz wymusić strukturę obiektu za pomocą interfejsu
  • lepsze autouzupełnianie w IDE
  • nie otrzymujesz powiadomień o niezdefiniowanych kluczach tablicowych
  • w końcu możesz łatwo przekonwertować dowolny obiekt na tablicę

OOP ! = AOP :)

(Na przykład w Rubim wszystko jest obiektem. PHP był wcześniej językiem proceduralnym / skryptowym).

takeshin
źródło
7

WordPress (i sporo innych aplikacji PHP) używa raczej obiektów niż tablic ze względów koncepcyjnych, a nie technicznych.

Obiekt (nawet jeśli jest to tylko instancja stdClass) jest reprezentacją jednej rzeczy. W WordPress może to być post, komentarz lub użytkownik. Z drugiej strony tablica to zbiór rzeczy. (Na przykład lista postów).

Historycznie rzecz biorąc, PHP nie miało doskonałej obsługi obiektów, więc tablice stały się dość potężne na początku. (Na przykład możliwość posiadania dowolnych kluczy, a nie tylko ich indeksowania zerowego). Dzięki obsłudze obiektów dostępnej w PHP 5 programiści mają teraz wybór między używaniem tablic lub obiektów jako magazynów klucz-wartość. Osobiście wolę podejście WordPress, ponieważ podoba mi się różnica składniowa między „jednostkami” a „kolekcjami”, które zapewniają obiekty i tablice.

Seb Pollard
źródło
5

Moje pytanie brzmi: dlaczego oni (Wordpress) używają obiektów zamiast tablic?

To naprawdę dobre pytanie, na które nie jest łatwo odpowiedzieć. Mogę tylko założyć, że w Wordpress często używa się stdClassobiektów, ponieważ używają one klasy bazy danych, która domyślnie zwraca rekordy jako stdClassobiekt. Przyzwyczaili się do tego (8 lat i więcej) i to wszystko. Nie sądzę, żeby za tym prostym faktem kryło się dużo więcej przemyśleń.

cukier syntaktyczny dla tablic asocjacyjnych - Zeev Suraski o obiekcie standardowym od PHP 3

  • stdClassobiekty nie są tak naprawdę lepsze niż tablice. Są prawie takie same. Dzieje się tak z pewnych powodów historycznych, ponieważ język i stdClassprzedmioty są naprawdę ograniczone i w rzeczywistości są tylko rodzajem obiektów wartościowych w bardzo podstawowym sensie.
  • stdClassobiekty przechowują wartości dla swoich członków, podobnie jak tablica dla każdego wpisu. I to wszystko.
  • Tylko maniacy PHP mogą tworzyć stdClassobiekty z prywatnymi członkami. Nie ma zbyt wiele korzyści - jeśli w ogóle - takie postępowanie.
  • stdClassobiekty nie mają żadnych metod / funkcji. Więc nie używaj tego w Wordpress.
  • W porównaniu z arraynimi istnieją znacznie mniej przydatne funkcje do radzenia sobie z listą lub danymi częściowo ustrukturyzowanymi.

Jeśli jednak jesteś przyzwyczajony do tablic, po prostu rzuć:

$array = (array) $object;

Możesz uzyskać dostęp do danych, które wcześniej były obiektem, jako tablica. Lub lubisz to na odwrót:

$object = (object) $array;

Co spowoduje tylko usunięcie nieprawidłowych nazw członków, takich jak liczby. Więc uważaj. Ale myślę, że masz szerszy obraz: nie ma dużej różnicy, jeśli chodzi o tablice i obiekty stdClass.

Związane z:

hakre
źródło
4
  1. W ten sposób kod wygląda fajniej
  2. Obiekty są przekazywane przez odniesienie
  3. Obiekty są silniej wpisywane niż tablice, stąd zaimki na błędy (lub wyświetlają znaczący komunikat o błędzie, gdy próbujesz użyć nieistniejącego elementu członkowskiego)
  4. Wszystkie dzisiejsze IDE mają funkcję autouzupełniania, więc podczas pracy z określonymi obiektami IDE wiele robi za Ciebie i przyspiesza działanie
  5. Z łatwością hermetyzuj logikę i dane w tym samym pudełku, w którym za pomocą tablic przechowujesz dane w tablicy, a następnie wykorzystujesz zestaw różnych funkcji do ich przetwarzania.
  6. Dziedziczenie, gdybyś miał podobną tablicę z prawie, ale nie podobną funkcjonalnością, musiałbyś powielić więcej kodu niż gdybyś miał to zrobić z obiektami

Prawdopodobnie jakiś inny powód, o którym myślałem

Itay Moav -Malimovka
źródło
„# Obiekty są przekazywane przez odniesienie”: To źle. Obiekty nie są przekazywane jako odwołania do zmiennych PHP. Nigdy tego nie zrobili.
hakre
@hakre - czy korzystasz z php4? lub wyjaśnij, co masz na myśli.
Itay Moav -Malimovka
Cóż, nie to, że wordpress do niedawna nie był PHP 4, ale w PHP 4 lub PHP 5 obiekty nie są traktowane jako odniesienie: "Jednym z kluczowych punktów PHP5 OOP, o którym często się wspomina, jest to, że" obiekty są przekazywane domyślnie przez odwołania " . To nie jest do końca prawdą. Ta sekcja poprawia tę ogólną myśl na kilku przykładach ”. Obiekty i odniesienia
hakre
@hakre - Rozumiem, co masz na myśli, ale pod każdym względem język zachowuje się tak, jakbyś przekazywał tylko referencje.
Itay Moav -Malimovka
4

Obiekty są znacznie potężniejsze niż tablice. Każdy obiekt jako instancja klasy może mieć dołączone funkcje. Jeśli masz dane, które wymagają przetwarzania, potrzebujesz funkcji, która je przetwarza. Mając tablicę, musiałbyś wywołać tę funkcję na tej tablicy i samemu skojarzyć logikę z danymi. Z obiektem to skojarzenie jest już zrobione i nie musisz już się tym przejmować.

Powinieneś także wziąć pod uwagę zasadę OO ukrywania informacji. Nie wszystko, co wraca z bazy danych lub do niej trafia, powinno być bezpośrednio dostępne.

Nikt nie odchodzi od SE
źródło
Wordpress zwraca obiekty klasy StdClass. Te obiekty nie mają nic wspólnego z tym, co podkreślasz. Na przykład nie mają funkcji i nie mają dziedziczenia. W przypadku Wordpress wszystkie zmienne klas są publiczne.
hakre
Tak, to prawda. Myślę, że w tym przypadku jest tak, jak stwierdzili inni, w zależności od tego, co wolisz. Nie jestem w wordpressie, ale prawdopodobnie hermetyzują wszystkie wywołania bazy danych i dlatego nie mogą zapewnić żadnej wyspecjalizowanej klasy do zwracania. Ale moja odpowiedź była ogólna i myślę, że twórcy poczynili podobne uwagi ... Albo po prostu rzucili monetą.
Nikt nie wyprowadza się z SE
Po prostu używają klasy pomocniczej bazy danych, która stdClassdomyślnie zwraca obiekty od ok. 8 lat. Jeśli chcesz uzyskać tablicę, musisz ustawić opcjonalny parametr, aby ją uzyskać.
hakre
3

Istnieje kilka powodów, dla których warto zwrócić obiekty:

  1. Pisanie $myObject->propertywymaga mniej znaków „narzutowych” niż$myArray['element']

  2. Obiekt może zwrócić dane i funkcjonalność; tablice mogą zawierać tylko dane.

  3. Włącz łączenie: $myobject->getData()->parseData()->toXML();

  4. Łatwiejsze kodowanie: autouzupełnianie IDE może dostarczyć wskazówek dotyczących metod i właściwości obiektu.

Pod względem wydajności tablice są często szybsze niż obiekty. Oprócz wydajności istnieje kilka powodów, dla których warto używać tablic:

  1. Funkcjonalność zapewniana przez rodzinę funkcji array _ * () może w niektórych przypadkach zmniejszyć ilość kodowania niezbędnego.

  2. Operacje takie jak count () i foreach () mogą być wykonywane na tablicach. Obiekty tego nie oferują (chyba że implementują Iterator lub Countable ).

George Cummins
źródło
2

Zwykle nie będzie to spowodowane wydajnością. Zazwyczaj obiekty kosztują więcej niż tablice.

W przypadku wielu interfejsów API ma to prawdopodobnie związek z obiektami zapewniającymi inne funkcje poza mechanizmem przechowywania. W przeciwnym razie jest to kwestia preferencji i zwracanie obiektu w porównaniu z tablicą nie przynosi żadnych korzyści.

simshaun
źródło
W PHP5 różnica w wydajności między tablicami i obiektami jest znikoma.
Justin ᚅᚔᚈᚄᚒᚔ
2

Tablica to tylko indeks wartości. Natomiast obiekt zawiera metody, które mogą wygenerować wynik dla Ciebie. Jasne, czasami można uzyskać bezpośredni dostęp do wartości obiektów, ale „właściwym sposobem na zrobienie tego” jest dostęp do metod obiektów (funkcji operującej na wartościach tego obiektu).

$obj = new MyObject;
$obj->getName();   // this calls a method (function), so it can decide what to return based on conditions or other criteria

$array['name'];   // this is just the string "name". there is no logic to it. 

Czasami uzyskujesz dostęp do zmiennych obiektów bezpośrednio, zwykle jest to mile widziane, ale zdarza się to nadal dość często.

$obj->name;   // accessing the string "name" ... not really different from an array in this case.

Należy jednak wziąć pod uwagę, że klasa MyObject nie ma zmiennej o nazwie „name”, ale zamiast tego ma zmienne first_name i last_name.

$obj->getName();  // this would return first_name and last_name joined.
$obj->name;  // would fail...
$obj->first_name; 
$obj->last_name; // would be accessing the variables of that object directly.

To bardzo prosty przykład, ale możesz zobaczyć, dokąd to zmierza. Klasa zawiera zbiór zmiennych i funkcji, które mogą operować na tych zmiennych w ramach samodzielnej jednostki logicznej. Wystąpienie tej jednostki nazywa się obiektem i wprowadza logikę i dynamiczne wyniki, których tablica po prostu nie ma.

Nick Jennings
źródło
1

W większości przypadków obiekty są tak samo szybkie, jeśli nie szybsze niż tablice, w PHP nie ma zauważalnej różnicy. głównym powodem jest to, że obiekty są potężniejsze niż tablice. Programowanie obiektowe pozwala na tworzenie obiektów i przechowywanie nie tylko danych, ale także funkcjonalność w nich, na przykład w PHP klasa MySQLi pozwala na posiadanie obiektu bazy danych, którym można manipulować za pomocą wielu wbudowanych funkcji, zamiast podejścia proceduralnego.

Więc głównym powodem jest to, że OOP jest doskonałym paradygmatem. Napisałem artykuł o tym, dlaczego używanie OOP jest dobrym pomysłem, a wyjaśniając koncepcję, możesz zajrzeć tutaj: http://tomsbigbox.com/an-introduction-to-oop/

Jako drobny plus wpisujesz również less, aby pobrać dane z obiektu - $ test-> data jest lepsze niż $ test ['data'].

Tom Walters
źródło
1

Nie znam prasy słownej. Wiele odpowiedzi sugeruje, że siła obiektów polega na tym, że zawierają one funkcjonalny kod. Zwracając obiekt z wywołania funkcji / API, nie powinien on zawierać funkcji narzędziowych. Tylko właściwości.

Siła zwracania obiektów polega na tym, że wszystko, co kryje się za API, może ulec zmianie bez łamania kodu.

Przykład: Otrzymujesz tablicę danych z parami klucz / wartość, klucz reprezentujący kolumnę DB. Jeśli nazwa kolumny DB zostanie zmieniona, kod zostanie uszkodzony.

Josh Johnson
źródło
1

Przeprowadzam następny test w php 5.3.10 (Windows):

for ($i = 0; $i < 1000000; $i++) {
    $x = array();
    $x['a'] = 'a';
    $x['b'] = 'b';
}

i

for ($i = 0; $i < 1000000; $i++) {
    $x = new stdClass;
    $x->a = 'a';
    $x->b = 'b';
}

Skopiowano z http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961

Wywołanie funkcji dla 10 jednoczesnych użytkowników i 10 razy (w celu uzyskania średniej)

  • Tablice: 100%
  • Obiekt: 214% - 216% (2 razy wolniej).

AKA, obiekt, to wciąż jest bolesne, powolne. OOP utrzymuje porządek, ale należy go używać ostrożnie.

Jaki Wordpress stosuje? Cóż, oba rozwiązania wykorzystują obiekty, tablice oraz obiekt i tablice, klasa wpdb używa późniejszego (i jest to serce Wordpress).

magallanes
źródło
Powinieneś zobaczyć porównanie w PHP 5.4. Wydajność obiektów jest znakomita, a czasem nawet szybsza niż w przypadku tablic.
Sanket Sahu
0

Jest zgodny z zasadą pakowania i unboxingu OOP. Podczas gdy języki takie jak Java i C # obsługują to natywnie, PHP nie. Jednak można to osiągnąć, do pewnego stopnia w PHP, ale nie elokwentnie, ponieważ sam język nie ma konstrukcji do jego obsługi. Posiadanie typów pól w PHP może pomóc w tworzeniu łańcuchów, utrzymaniu wszystkiego zorientowanego obiektowo i pozwala na podpowiadanie typów w podpisach metod. Wadą jest narzut i fakt, że masz teraz dodatkowe sprawdzenie do wykonania przy użyciu konstrukcji „instancja”. Posiadanie systemu typów jest również zaletą w przypadku korzystania z narzędzi programistycznych, które mają funkcję Intellisense lub asystenta kodu, takich jak PDT. Zamiast szukać metody w Google / bing / yahoo, istnieje ona w obiekcie i możesz użyć narzędzia do udostępnienia listy rozwijanej.

LEMUEL ADANE
źródło
0

Chociaż uwagi dotyczące obiektów, które są czymś więcej niż tylko danymi, są ważne, ponieważ zwykle są to dane i zachowanie, istnieje co najmniej jeden wzorzec wspomniany w Wzorcach architektury aplikacji korporacyjnych” Martina Fowlera, który odnosi się do tego typu cenario, w których dokonujesz transferu dane z jednego systemu (aplikacja za API) i innego (Twoja aplikacja).

Jest to obiekt transferu danych - obiekt, który przenosi dane między procesami w celu zmniejszenia liczby wywołań metod.

Więc jeśli pytanie brzmi, czy interfejsy API powinny zwracać DTO lub tablicę, powiedziałbym, że jeśli koszt wydajności jest znikomy, powinieneś wybrać opcję, która jest łatwiejsza w utrzymaniu, którą uważam za opcję DTO ... ale oczywiście ty też Musisz wziąć pod uwagę umiejętności i kulturę zespołu, który opracowuje Twój system oraz język lub wsparcie IDE dla każdej z opcji.

Vitor Silva
źródło