Perché restituire un oggetto invece di un array?


84

Lavoro molto in WordPress e ho notato che molte più funzioni restituiscono oggetti che array. I risultati del database vengono restituiti come oggetti a meno che non si richieda specificamente un array. Gli errori vengono restituiti come oggetti. Al di fuori di WordPress, la maggior parte delle API ti offre un oggetto invece di un array.

La mia domanda è: perché usano oggetti invece di array? Per la maggior parte non ha molta importanza, ma in alcuni casi trovo gli oggetti più difficili non solo da elaborare, ma da avvolgere la testa. C'è un motivo di prestazione per l'utilizzo di un oggetto?

Sono un programmatore PHP autodidatta. Ho una laurea in arti liberali. Quindi perdonami se mi manca un aspetto fondamentale dell'informatica. ;)


5
Sono curioso di questo per quanto riguarda gli svantaggi degli oggetti, come non essere in grado di usarli count()o array_*()funzioni su di essi (almeno per quanto riguarda la memorizzazione / restituzione di dati chiave => valore). Nessuno sembra parlarne o mi sto perdendo qualcosa?
Wesley Murch

8
Gli oggetti possono essere resi numerabili e iterabili implementando interfacce Countable o Iterator. Controlla anche php.net/manual/en/book.spl.php .
simshaun

Se è installato SPL e si implementa l'interfaccia numerabile per la propria classe di oggetti, è possibile chiamare count()un oggetto.
Nessuno si allontana da SE il

2
In molti molti casi, un array non ha nemmeno senso perché non restituisci una raccolta di oggetti o un tipo di raccolta che non è facilmente emulata con gli array. Quando hai solo una sequenza di altri valori e nessuna semantica aggiuntiva associata, per l'amor di Dio restituisci un array, ma scoprirai che è raro che sia così.

8
@delnan e altri: si prega di notare che @Dennis sta parlando di array associativi , (aka. dizionari, aka. Maps), non di array normali (integer-index). Queste sono una caratteristica fondamentale di PHP e hanno più o meno lo stesso scopo delle classi dinamiche ( stdClass). Non sono sicuro che questa domanda abbia una risposta diversa da "Perché i programmatori che lavorano principalmente in OOP preferiscono la semantica dell'uso degli oggetti"
BlueRaja - Danny Pflughoeft

Risposte:


63

Questi sono i motivi per cui preferisco gli oggetti in generale:

  • Gli oggetti non contengono solo dati ma anche funzionalità.
  • Gli oggetti hanno (nella maggior parte dei casi) una struttura predefinita. Questo è molto utile per la progettazione delle API. Inoltre, puoi impostare le proprietà come pubbliche, protette o private.
  • gli oggetti si adattano meglio allo sviluppo orientato agli oggetti.
  • Nella maggior parte degli IDE l'auto-completamento funziona solo per gli oggetti.

Ecco qualcosa da leggere:


3
il primo collegamento sembra non essere buono? Voglio dire, funziona, ma richiede un articolo diverso
Geo

24

Questo probabilmente non è qualcosa che capirai a fondo fino a quando non avrai lavorato a un grande progetto software per diversi anni. Molte nuove major di informatica ti daranno una risposta con tutte le parole giuste (incapsulamento, funzionalità con i dati e manutenibilità) ma pochi capiranno davvero perché tutta quella roba è buona da avere.

Esaminiamo alcuni esempi.

  • Se sono stati restituiti array, allora o tutti i valori devono essere calcolati in anticipo o devono essere restituiti molti piccoli valori con cui è possibile creare i valori più complessi.

Pensa a un metodo API che restituisce un elenco di post di WordPress. Questi post hanno tutti autori, gli autori hanno nomi, indirizzi e-mail, forse anche profili con le loro biografie.

Se stai restituendo tutti i post in un array, dovrai limitarti a restituire un array di ID post:

[233, 41, 204, 111]

o restituendo un enorme array che assomiglia a qualcosa di simile:

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

Il primo caso di restituzione di un elenco di ID non è molto utile perché in tal caso è necessario effettuare una chiamata API per ciascun ID per ottenere alcune informazioni su quel post.

Il secondo caso raccoglierà molte più informazioni di quelle necessarie il 90% delle volte e farà molto più lavoro (specialmente se uno di questi campi è molto complicato da costruire).

Un oggetto d'altra parte può fornirti l'accesso a tutte le informazioni di cui hai bisogno, ma non le hai ancora estratte. La determinazione dei valori dei campi può essere eseguita pigramente (cioè, quando il valore è necessario e non in anticipo) quando si utilizza un oggetto.

  • Gli array espongono più dati e funzionalità del previsto

Torna all'esempio dell'enorme array restituito. Ora qualcuno potrebbe probabilmente costruire un'applicazione che itera su ogni valore all'interno dell'array di post e lo stampa. Se l'API viene aggiornata per aggiungere solo un elemento in più a quell'array di post, il codice dell'applicazione si interromperà poiché stamperà un nuovo campo che probabilmente non dovrebbe. Se l'ordine degli elementi nell'array di post restituito dall'API cambia, anche il codice dell'applicazione verrà interrotto. Quindi la restituzione di un array crea tutti i tipi di possibili dipendenze che un oggetto non creerebbe.

  • Funzionalità

Un oggetto può contenere informazioni al suo interno che gli consentiranno di fornirti funzionalità utili. Un oggetto post, ad esempio, potrebbe essere abbastanza intelligente da restituire i post precedenti o successivi. Un array non potrebbe mai farlo per te.

  • Flessibilità

Tutti i vantaggi degli oggetti sopra menzionati aiutano a creare un sistema più flessibile.


10

La mia domanda è: perché usano oggetti invece di array?

Probabilmente due ragioni:

  • WordPress è piuttosto vecchio
  • gli array sono più veloci e richiedono meno memoria nella maggior parte dei casi
  • più facile da serializzare

C'è un motivo di prestazione per l'utilizzo di un oggetto?

No. Ma molte altre buone ragioni, ad esempio:

  • puoi memorizzare la logica negli oggetti (metodi, chiusure, ecc.)
  • puoi forzare la struttura degli oggetti usando un'interfaccia
  • migliore autocompletamento nell'IDE
  • non si ottengono avvisi per chiavi di array non indefinite
  • alla fine, puoi convertire facilmente qualsiasi oggetto in array

OOP ! = AOP :)

(Ad esempio, in Ruby, tutto è un oggetto. PHP era un linguaggio procedurale / di scripting in precedenza.)


7

WordPress (e una discreta quantità di altre applicazioni PHP) utilizza oggetti piuttosto che array, per ragioni concettuali piuttosto che tecniche.

Un oggetto (anche se solo un'istanza di stdClass) è una rappresentazione di una cosa. In WordPress potrebbe essere un post, un commento o un utente. Un array, d'altra parte, è una raccolta di cose. (Ad esempio, un elenco di post.)

Storicamente, PHP non ha avuto un grande supporto agli oggetti, quindi gli array sono diventati abbastanza potenti all'inizio. (Ad esempio, la possibilità di avere chiavi arbitrarie invece di essere semplicemente indicizzate a zero.) Con il supporto per gli oggetti disponibile in PHP 5, gli sviluppatori ora possono scegliere se utilizzare array o oggetti come archivi di valori-chiave. Personalmente, preferisco l'approccio WordPress in quanto mi piace la differenza sintattica tra "entità" e "raccolte" fornite da oggetti e array.


5

La mia domanda è: perché (Wordpress) usano oggetti invece di array?

Questa è davvero una buona domanda e non è facile rispondere. Posso solo presumere che sia comune in Wordpress utilizzare gli stdClassoggetti perché stanno utilizzando una classe di database che per impostazione predefinita restituisce i record come stdClassoggetto. Si sono abituati (8 anni e più) e basta. Non credo che ci sia molto più pensiero dietro il semplice fatto.

zucchero sintattico per array associativi - Zeev Suraski sull'oggetto standard da PHP 3

  • stdClassgli oggetti non sono realmente migliori degli array. Sono praticamente la stessa cosa. Questo per alcune ragioni storiche del linguaggio, così come gli stdClassoggetti sono davvero limitati e in realtà sono solo una sorta di oggetti di valore in un senso molto elementare.
  • stdClassgli oggetti memorizzano i valori per i loro membri come fa un array per voce. E questo è tutto.
  • Solo i fanatici di PHP sono in grado di creare stdClassoggetti con membri privati. Non c'è molto vantaggio - se del caso - farlo.
  • stdClassgli oggetti non hanno metodi / funzioni. Quindi non usarlo in Wordpress.
  • Rispetto a array, ci sono funzioni molto meno utili per gestire un elenco o dati semi-strutturati.

Tuttavia, se sei abituato agli array, lancia:

$array = (array) $object;

E puoi accedere ai dati che in precedenza erano un oggetto, come un array. O ti piace il contrario:

$object = (object) $array;

Che farà cadere solo i nomi dei membri non validi, come i numeri. Quindi fai un po 'di attenzione. Ma penso che tu abbia il quadro generale: non c'è molta differenza fintanto che si tratta di array e oggetti di stdClass.

Relazionato:


4
  1. Il codice sembra più interessante in questo modo
  2. Gli oggetti passano per riferimento
  3. Gli oggetti sono tipizzati più forte rispetto agli array, quindi lees pron agli errori (o ti danno un messaggio di errore significativo quando provi a usare un membro non esistente)
  4. Tutti gli IDE oggi hanno il completamento automatico, quindi quando si lavora con oggetti definiti, l'IDE fa molto per te e velocizza le cose
  5. Incapsula facilmente logica e dati nella stessa scatola, dove con gli array, memorizzi i dati nell'array e quindi utilizzi un set di funzioni diverse per elaborarli.
  6. Ereditarietà, se avessi un array simile con funzionalità quasi ma non simili, dovresti duplicare più codice allora se devi farlo con gli oggetti

Probabilmente qualche motivo in più a cui ho pensato


"# Gli oggetti passano per riferimento": È sbagliato. Gli oggetti non vengono passati come riferimento a una variabile PHP. Non l'hanno mai fatto.
hakre

@hakre - sei su php4? o per favore elabora quello che intendi.
Itay Moav -Malimovka

Beh, non che wordpress non fosse PHP 4 fino a poco tempo fa, ma in PHP 4 o PHP 5, gli oggetti non vengono passati come riferimento: "Uno dei punti chiave di PHP5 OOP che viene spesso menzionato è che" gli oggetti vengono passati per riferimento per impostazione predefinita " . Questo non è completamente vero. Questa sezione rettifica quel pensiero generale usando alcuni esempi. " Oggetti e riferimenti
hakre

@hakre - Capisco cosa intendi, ma a tutti gli effetti, la lingua si comporta come se passassi solo riferimenti.
Itay Moav -Malimovka

4

Gli oggetti sono molto più potenti di quanto possano essere gli array. Ogni oggetto come istanza di una classe può avere funzioni associate. Se si dispone di dati che necessitano di elaborazione, è necessaria una funzione che esegua l'elaborazione. Con un array dovresti chiamare quella funzione su quell'array e quindi associare tu stesso la logica ai dati. Con un oggetto questa associazione è già fatta e non devi più preoccupartene.

Inoltre dovresti considerare il principio OO dell'occultamento delle informazioni. Non tutto ciò che ritorna o va al database dovrebbe essere direttamente accessibile.


Wordpress restituisce gli oggetti della classe StdClass. Quegli oggetti non hanno nulla in comune con ciò che evidenzi. Non hanno funzioni per esempio e non hanno ereditarietà. E nel caso di Wordpress, tutte le variabili di classe sono pubbliche.
hakre

Sì è vero. Penso che in questo caso sia, come altri hanno affermato, solo a seconda di ciò che preferisci. Non sono in wordpress ma probabilmente incapsulano tutte le chiamate al database e quindi non possono fornire alcuna classe specializzata per la restituzione. Ma la mia risposta è stata in generale e penso che considerazioni simili siano state fatte dai creatori ... Oppure hanno semplicemente lanciato una moneta.
Nessuno si allontana da SE il

Usano solo una classe di supporto del database che restituisce stdClassoggetti per impostazione predefinita da ca. 8 anni. Se vuoi ottenere un array, devi impostare un parametro opzionale per ottenerlo.
hakre

3

Esistono diversi motivi per restituire gli oggetti:

  1. La scrittura $myObject->propertyrichiede meno caratteri "generali" di$myArray['element']

  2. L'oggetto può restituire dati e funzionalità; gli array possono contenere solo dati.

  3. Abilita concatenamento: $myobject->getData()->parseData()->toXML();

  4. Codifica più semplice: il completamento automatico IDE può fornire suggerimenti su metodi e proprietà per l'oggetto.

In termini di prestazioni, gli array sono spesso più veloci degli oggetti. Oltre alle prestazioni, esistono diversi motivi per utilizzare gli array:

  1. La funzionalità fornita dalla famiglia di funzioni array _ * () può ridurre la quantità di codifica necessaria in alcuni casi.

  2. Operazioni come count () e foreach () possono essere eseguite sugli array. Gli oggetti non lo offrono (a meno che non implementino Iterator o Countable ).


2

Di solito non sarà per motivi di prestazioni. In genere, gli oggetti costano più degli array.

Per molte API, probabilmente ha a che fare con gli oggetti che forniscono altre funzionalità oltre ad essere un meccanismo di archiviazione. Altrimenti, è una questione di preferenza e non c'è davvero alcun vantaggio nel restituire un oggetto rispetto a un array.


In PHP5, la differenza di prestazioni tra array e oggetti è marginale.
Justin ᚅᚔᚈᚄᚒᚔ

2

Un array è solo un indice di valori. Mentre un oggetto contiene metodi che possono generare il risultato per te. Certo, a volte è possibile accedere direttamente ai valori di un oggetto, ma il "modo giusto per farlo" è accedere ai metodi di un oggetto (una funzione che opera sui valori di quell'oggetto).

$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. 

A volte si accede direttamente alle variabili di un oggetto, di solito questo è disapprovato, ma accade ancora abbastanza spesso.

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

Tuttavia, considera che la classe MyObject non ha una variabile chiamata "name", ma ha invece una variabile first_name e 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.

Questo è un esempio molto semplice, ma puoi vedere dove sta andando. Una classe fornisce una raccolta di variabili e le funzioni che possono operare su quelle variabili, il tutto all'interno di un'entità logica autonoma. Un'istanza di quell'entità è chiamata oggetto e introduce risultati logici e dinamici, che un array semplicemente non ha.


1

La maggior parte delle volte gli oggetti sono altrettanto veloci, se non più veloci degli array, in PHP non c'è una differenza evidente. il motivo principale è che gli oggetti sono più potenti degli array. La programmazione orientata agli oggetti ti consente di creare oggetti e memorizzare non solo dati, ma funzionalità in essi, ad esempio in PHP la classe MySQLi ti consente di avere un oggetto database che puoi manipolare utilizzando una serie di funzioni integrate, piuttosto che l'approccio procedurale.

Quindi il motivo principale è che l'OOP è un eccellente paradigma. Ho scritto un articolo sul perché usare OOP è una buona idea e, spiegando il concetto, puoi dare un'occhiata qui: http://tomsbigbox.com/an-introduction-to-oop/

Come plus minore, digiti anche less per ottenere dati da un oggetto: $ test-> data è migliore di $ test ['data'].


1

Non ho familiarità con la stampa di parole. Molte risposte qui suggeriscono che un punto di forza degli oggetti è la capacità di contenere codice funzionale. Quando si restituisce un oggetto da una chiamata di funzione / API, non dovrebbe contenere funzioni di utilità. Solo proprietà.

Il punto di forza nel restituire gli oggetti è che tutto ciò che sta dietro l'API può cambiare senza rompere il codice.

Esempio: ottieni un array di dati con coppie chiave / valore, chiave che rappresenta la colonna DB. Se la colonna DB viene rinominata, il codice verrà interrotto.


1

Sto eseguendo il prossimo test in php 5.3.10 (Windows):

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

e

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

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

Chiamando la funzione per 10 utenti simultanei e 10 volte (per ottenere una media) quindi

  • Array: 100%
  • Oggetto: 214% - 216% (2 volte più lento).

AKA, Object è ancora doloroso lento. OOP mantiene le cose in ordine, tuttavia dovrebbe essere usato con attenzione.

Che cosa Wordpress sta applicando ?. Ebbene, entrambe le soluzioni, utilizzano oggetti, array e object & array, Class wpdb utilizza il successivo (ed è il cuore di Wordpress).


Dovresti vedere il confronto su PHP 5.4. Le prestazioni degli oggetti sono eccezionali e talvolta anche più veloci degli array.
Sanket Sahu

0

Segue il principio di boxe e unboxing di OOP. Sebbene linguaggi come Java e C # lo supportino in modo nativo, PHP non lo supporta. Tuttavia può essere realizzato, in una certa misura in PHP, solo in modo non eloquente poiché il linguaggio stesso non ha costrutti per supportarlo. Avere i box type in PHP potrebbe aiutare con il concatenamento, mantenendo tutto orientato agli oggetti e consente il suggerimento del tipo nelle firme dei metodi. Lo svantaggio è il sovraccarico e il fatto che ora hai un controllo extra da fare usando il costrutto "istanza di". Avere un sistema di tipi è anche un vantaggio quando si utilizzano strumenti di sviluppo con intelligenza o assistenza al codice come PDT. Invece di dover cercare su google / bing / yahoo il metodo, esiste sull'oggetto e puoi utilizzare lo strumento per fornire un menu a discesa.


0

Sebbene i punti fatti sugli oggetti che sono più che semplici dati siano validi poiché di solito sono dati e comportamenti, c'è almeno un modello menzionato in "Patterns of Enterprise Application Architecture" di Martin Fowler che si applica a questo tipo di cenario in cui stai trasferendo dati da un sistema (l'applicazione dietro l'API) e un altro (la tua applicazione).

È l' oggetto di trasferimento dati - Un oggetto che trasporta i dati tra i processi al fine di ridurre il numero di chiamate al metodo.

Quindi, se la domanda è se le API debbano restituire un DTO o un array, direi che se il costo delle prestazioni è trascurabile, dovresti scegliere l'opzione più gestibile che direi è l'opzione DTO ... ma ovviamente anche tu devi considerare le competenze e la cultura del team che sta sviluppando il tuo sistema e il supporto linguistico o IDE per ciascuna delle opzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.