2009-04-04 21 views
56

Ci sono alcuni post su questo argomento, ma non ho capito chiaramente quando utilizzare la codifica orientata agli oggetti e quando utilizzare le funzioni programmatiche in un include. Qualcuno mi ha anche detto che OOP è molto pesante da eseguire e rende più carico di lavoro. È giusto?Perché utilizzare PHP OOP su funzioni di base e quando?

Diciamo che ho un grande file con 50 funzioni. Perché dovrei chiamarli in una classe? E non per function_name()? Devo cambiare e creare un oggetto che contiene tutte le mie funzioni? Quale sarà il vantaggio o la differenza specifica? Quali vantaggi porta a codificare OOP in PHP? Modularità?

+1

Ho scritto un post sul blog qualche tempo fa che potrebbe aiutarti a capire la differenza: [Procedural vs. OOP Explained] (http://www.virtuosimedia.com/tutorials/procedural-vs-oop-explained) – VirtuosiMedia

risposta

40

In molti scenari, la programmazione procedurale va bene.L'uso di OO per il suo utilizzo è inutile, specialmente se si finisce con gli oggetti POD (plain-old-data).

Il potere di OO deriva principalmente dall'ereditarietà e dal polimorfismo. Se usi le classi, ma non usi mai uno di questi due concetti, probabilmente non hai bisogno di usare una classe in primo luogo.

Uno dei posti più belli in cui OO si illumina, consente di eliminare il codice di attivazione. Considerate:

function drive($the_car){ 

    switch($the_car){ 

     case 'ferrari': 
      $all_cars->run_ferrari_code(); 
      break; 

     case 'mazerati': 
      $all_cars->run_mazerati_code(); 
      break; 

     case 'bentley': 
      $all_cars->run_bentley_code(); 
      break; 
    } 
} 

con la sua alternativa OO:

function drive($the_car){ 

    $the_car->drive(); 
} 

polimorfismo permetterà il corretto tipo di "guida" per accadere, sulla base di informazioni di runtime.


Note polimorfismo:

Il secondo esempio qui ha alcune premesse: cioè che tutte le classi di auto sarà o estendere una classe abstract o implementare un interface.

Entrambi consentono di forzare l'estensione o l'implementazione di classi per definire una funzione specifica, ad esempio drive(). Questo è molto potente in quanto ti permette di drive() tutte le auto senza dover sapere quale stai guidando; questo perché stanno estendendo una classe astratta contenente il metodo drive() o implementando un'interfaccia che impone la definizione del metodo drive().

Quindi, fintanto che è assicurarsi che tutte le vostre auto specifiche estendere la classe astratta car o implementano un'interfaccia come canBeDriven (entrambi i quali devono dichiarare il metodo drive()) si può chiamare il metodo drive() su un oggetto che tu sai essere una macchina (ma non che tipo di macchina) senza paura di non essere definito, poichè PHP genererà errori fatali fino a quando non definirai quei metodi nelle tue specifiche classi di auto.

+10

non si ottiene il tuo esempio alternativo. – Codex73

+2

se si utilizza un OOP corretto, $ the_car potrebbe puntare a qualsiasi tipo di auto. Poiché tutti i diversi tipi di auto hanno un metodo drive(), puoi tranquillamente chiamarlo, indipendentemente dal tipo di auto. A runtime, sa che tipo di macchina è, e chiama automaticamente quella giusta. –

+10

appena trovato questo e non ottenere l'esempio alternativo neanche. Stai solo passando un oggetto a una funzione e chiamando drive(). Immaginando di definire l'oggetto durante l'istanziazione ma non viene mostrato?Questo ha più senso come esempio di OOP $ car_object = new carClass ("$ the_car"); quindi esegui semplicemente $ car_object-> drive(); – Taylor

2

Se si hanno 50 funzioni anziché 50 metodi statici nella classe Utilities, si "inquina" lo spazio dei nomi globale.

Utilizzando una classe con 50 metodi statici, i nomi dei metodi sono locali per la classe.

+0

5.3 ha gli spazi dei nomi ... –

+0

Accetto! Ma il Codex non ha menzionato quale versione sta usando. Personalmente, sono ancora in 5.2.6 –

+2

Questo non è un argomento a favore di una vera programmazione orientata agli oggetti, che è ciò di cui tratta questa domanda; piuttosto, questo si riferisce al modello spesso usato di usare le classi per metodi di namespace altrimenti liberi. – Rob

12

L'utilizzo di un approccio di programmazione orientato agli oggetti piuttosto che un approccio di programmazione procedurale in un programma non dipende realmente dalla lingua (che si tratti di PHP o meno), ma dal tipo di problema che si sta tentando di risolvere.

(Sto solo andando a utilizzare pseudocodice nei miei esempi come io non sono troppo familiarità con PHP.)

Ad esempio, se si dispone di un programma in cui si sta solo eseguendo una serie di funzioni in ordine, allora procedurale sta andando bene. Ad esempio, se si tratta di un semplice programma di manipolazione delle stringhe, un approccio procedurale sarebbe sufficiente:

perform_truncation(my_string, 10) 
to_upper(my_string) 
perform_magic(my_string, hat, rabbit) 

Tuttavia, se si sta andando a che fare con molti elementi diversi (ad esempio file, o qualsiasi altra rappresentazione di, beh, oggetti) allora un approccio orientato agli oggetti sarebbe migliore.

Ad esempio, se si ha un po 'di Car s e li voleva drive, poi nel procedurale, si può fare qualcosa lungo la linea del:

drive_car(first_car) 
drive_car(second_car) 

Dove, come, in OOP, il Car lattina guidare se stesso:

E, poiché ogni automobile è una classe diversa, il loro comportamento può essere definito in modo diverso. Inoltre, possono essere entrambe sottoclassi o Car possono avere funzionalità comuni.

Si tratta in realtà del tipo di problema che rende l'approccio procedurale migliore rispetto all'oggetto e viceversa.

A parte il problema di procedurale o orientato agli oggetti, può essere una sorta di "odore di codice" per avere un file sorgente con molte funzioni. Questo vale anche per le classi che contengono molte funzionalità che possono essere meglio eseguite come funzioni separate in classi separate.

Il problema qui potrebbe essere l'organizzazione del codice piuttosto che decidere di scegliere la programmazione procedurale o orientata agli oggetti. Organizzare le funzioni in file sorgente separati può essere ciò che è necessario qui piuttosto che abbandonare l'approccio procedurale alla scrittura del programma.

Dopo tutto, ci sono molti programmi scritti nell'approccio procedurale di programmazione che è ben scritto e di facile manutenzione.

2

Non riesco a dire quale sia il migliore. ma nella mia esperienza puoi avere una migliore gestione del codice usando OOP. sapete quale codice è dove, quale funzionalità è definita in quale file, ecc. sul sovraccarico di runtime per OOP Ho letto da qualche parte (e penso sia vero) che se scrivete un codice errato in funzioni classiche, e lo stesso male codice in OOP, la versione della funzione funziona meglio. quindi se il tuo codice non è scritto male, non c'è alcuna prova che OOP stia mantenendo l'applicazione lenta. ricorda anche che queste cose "lente" e "overhead" sono tutte misurate in millisecondi. quindi se la tua applicazione non serve molti utenti (come più di 100 utenti in un minuto), potresti non notare alcuna differenza.

12

Cercherò di mantenere la mia risposta in aggiunta perché le risposte di Majd Taby e Coobird sono davvero buone.

Sono stato per la maggior parte un programmatore procedurale per diversi anni e non ho combattuto contro la programmazione OOP, ma non ho mai visto molta rilevanza ... cioè fino a quando non ho iniziato a lavorare su un team ea costruire progetti più importanti e complessi.

OOP brilla davvero, a mio parere, quando è necessario scrivere codice snello, facilmente manutenibile per applicazioni più complesse. E badate bene, non in ogni situazione, ma ci sono alcuni casi in cui procedurale semplicemente non funzionerà così bene.

La maggior parte dei miei esempi di grandi implementazioni OOP sono per progetti in cui ho avuto diverse cose che erano tutte correlate ma tutte leggermente diverse. Siti con molte forme, molti utenti, molti prodotti ecc.

Tutti hanno nomi di comportamento simili come print(), update(), ecc ... ma incapsulandoli come oggetti e variando le implementazioni dei metodi nelle classi posso rendere il mio codice in fase di esecuzione molto semplice e pulito in tutto il sito. Inoltre, e questo era fondamentale, nonostante avessi comportamenti diversi, ho potuto lavorare con oggetti diversi utilizzando le stesse chiamate di metodo nell'intera applicazione. Permette a un secondo sviluppatore di lavorare sull'attuazione reale mentre lavoro su un codice più profondo.

Non so se questo aiuti qualcuno, ma parlando come qualcuno che era nella tua situazione non molto tempo fa, adoro OOP.

2

OOP consente di creare contenitori strutturati di codice, denominati classi, che possono essere genitori/figli l'uno dell'altro. Questo può aiutare a creare un'applicazione in quanto è più facile da mantenere e può, se fatto correttamente ridurre la ridondanza del codice. OOP aggiunge un po 'di overhead, ma non è molto evidente ed è superato dall'invienibilità del codice procedurale. Se stai scrivendo una grande app, def o OO, specialmente se verrà utilizzata da molte persone.

Ad esempio, supponiamo di progettare un sito Web semplice. Potresti creare un oggetto Page. L'oggetto pagina è responsabile per andare al database e ottenere varie impostazioni per la pagina, come meta dati, tag titolo o anche il numero di determinati "componenti" sulla pagina e il loro tipo (come un controllo del calendario, un widget , eccetera).

Quindi, è possibile creare un'altra classe, ad esempio Indice, che estende Pagina. L'indice sarebbe l'indice o la pagina iniziale. Se disponi di un catalogo di prodotti, potresti avere una pagina di estensione della classe Catalog. Dal momento che sia la sezione del catalogo che la tua home page devono ottenere dati dal database riguardanti i metadati della pagina e la struttura di base della pagina, avere 1 oggetto che lo fa già per te aiuta. In entrambe queste situazioni, la pagina esegue tutto il lavoro e recupera i dati della pagina dal database, li carica in variabili, che sono quindi accessibili sia nella classe dell'indice che nella classe del catalogo. Non devi scrivere codice per andare nel database e riprovare in ogni pagina che scrivi.

Ora ci sono altri modi per farlo in modo procedurale, come con un include. Tuttavia, ti troverai a fare meno errori ed errori. Ad esempio, puoi definire un metodo astratto nella classe Page. Ciò significa che questo metodo DEVE essere definito in qualsiasi oggetto che lo estende. Ad esempio, hai creato una funzione setPageAttributes() come astratta nella classe Page. Quando lo fai, crei una funzione vuota. Quando crei la tua classe di indice, devi CREARE una funzione setPageAttributes() (con l'intento di riempirla, come accedere alle variabili definite nella classe Page e usarla per impostare gli elementi reali nella pagina, modello o vista che stai usando) o ottieni un errore PHP.

Se stai lavorando con altre persone per far scrivere il tuo progetto, i metodi astratti diranno alla persona: "Ehi, devi definire queste funzioni in qualsiasi codice che scrivi". Ciò ha costretto l'applicazione ad essere coerente.

Infine, non è possibile accedere a framework come i formati MVC se non si esegue OOP. Anche se non è necessario andare su MVC e c'è un dibattito, esso separa tutti i componenti dell'applicazione ed è necessario in ambienti in cui molte persone (designer, programmatori, impiegati di marketing) lavorano sullo stesso codice.

4

Diciamo che ho un grosso file con 50 funzioni, perché ti voglio chiamare questi in una classe?e non da nome_funzione(). Devo cambiare e creare l'oggetto che contiene tutte le mie funzioni ?

Passare a OOP non dovrebbe essere visto come un semplice "interruttore" nel modo in cui descrivi sopra.

OOP richiede un modo completamente diverso di pensare alla programmazione che comporta il ricablaggio del cervello. Poiché il ricablaggio di un cervello non avviene durante la notte, molte persone non sono disposte ad esporsi al processo di ricablaggio richiesto. Sfortunatamente il ricablaggio richiederà un investimento nel tempo e nello sforzo: ricerca, tutorial, tentativi ed errori.

Significa davvero fare un passo indietro e conoscere i concetti alla base di OOP, ma il rimborso sarà valsa la pena di parlare come qualcuno che ha attraversato questo processo nei giorni pre www.

Dopo aver 'capito' e seguire le migliori pratiche OOP nella tua quotidianità dirai agli altri come la tua vita di programmazione è cambiata in meglio.

Una volta compreso l'OOP, avrai risposto alla tua domanda.

+0

OOP è solo uno dei modi per scrivere MVC non usare oop e considerato cosa molto migliore –

0

La risposta accettata sembra aver trascurato di affermare che è possibile chiamare funzioni basate su un nome di variabile, come nell'esempio herew:

function drive($the_car){ 
    $the_car(); 
} 

Certo non ci sarebbe bisogno di essere una funzione per ogni auto in questo caso, ma è molto più efficiente rispetto alla dichiarazione switch suggerita.


variabili aggiuntive possono essere fornite facilmente come tale:

function operate($the_car,$action){ 
    $the_car($action); 
} 

function ferrari($action){ 
    switch($action){ 
     case 'drive': 
      echo 'Driving'; 
      break; 

     case 'stop': 
      echo 'Stopped'; 
      break; 

     default: return; 
    } 
} 


operate('ferrari','drive'); 

C'è un'istruzione switch qui ma è di fornire ulteriori funzionalità che non era nel esempio originale in modo che sia in alcun modo una contraddizione.

-1

Il concetto di OOP viene utilizzato in PHP, in modo da proteggere il codice. Poiché tutte le query sono scritte in un file di funzione anziché in un file di codice, nessuno può facilmente violare il nostro codice. Quindi è meglio usare le classi in PHP invece di scrivere direttamente le query.

Problemi correlati