Esempio di OOP in PHP nel mondo reale semplice?

1

Sto cercando di imparare PHP OOP, ma quando ho seguito i tutorial, tutti gli esempi sembrano implicare cose come:

class Human {
    $_sex;

    public function setSex($sex) {
        $this->_sex = $sex;
    }

    public function getSex() {
        return $this->sex;
    }
}

(Esempio senza valore, ma si spera che capisca cosa intendo: un oggetto ha proprietà che sono memorizzate nell'oggetto.)

Non ho mai incontrato un'applicazione web in cui avessi avuto bisogno di creare oggetti su umani, cani, auto o su altri strani esempi che trovi quando leggi i tutorial su OOP ...

Quindi sto cercando di trovare un progetto altrettanto semplice, ma più realistico, con cui imparare OOP. Ho scelto un sito web per un fumetto su Internet (ad esempio XKCD.com ). (Ciò consentirebbe alle persone di visualizzare il fumetto, ma anche all'autore di modificarlo e aggiornarlo.)

Quindi, come si tradurrebbe in PHP OOP nel mondo reale?

Il mio istinto iniziale sarebbe quello di rompere gli oggetti in questo modo:

  • Catalogo
  • Episodio

Dove la classe Catalogue conterrebbe metodi relativi a tutti gli episodi del fumetto, ad es. getMostRecentEpisodeID() , deleteEpisode($episodeID) , addNewEpisode($newEpisode) , ecc. ecc.

E Episode conterrebbe metodi relativi al singolo episodio, ad es. getEpisodeComments($episodeID) (se il sito web consente alle persone di lasciare commenti su singoli episodi), editEpisode($episodeID) , getEpisode($episodeID) , ecc.

È giusto o ho fatto un hash assoluto su cosa sia l'OOP?

Modifica: Piuttosto che limitarmi a fornirmi un elenco di esempi, sarebbe davvero utile se la tua risposta avesse un riferimento specifico al problema che sto cercando di risolvere.

Grazie.

    
posta Django Reinhardt 20.02.2013 - 18:52
fonte

2 risposte

3

Il problema con la programmazione orientata agli oggetti è esattamente questo, la forma e gli esempi del veicolo. Quello che scriverò qui sotto non è la verità, è un'opinione. Un'opinione condivisa da più persone di me solo però:)

Orientato agli oggetti rispetto a "Class oriented"

Il tuo esempio in cui ci sarebbe un catalogo e un episodio è perfettamente funzionante. Il problema è che le funzioni che proponi dovrebbero ottenere questi oggetti. È qui che si passa dalla programmazione orientata agli oggetti alla programmazione orientata alla classe. Adattare un sacco di metodi riguardanti lo stesso concetto in un oggetto non rende la programmazione orientata agli oggetti. Tutto quello che fai è creare una sorta di contenitore per i metodi.

L'oggetto episodio deve essere solo un oggetto che "modella" l'episodio. Ha un titolo, contenuto, autore, quel tipo di cose. In nessun modo questo episodio ha accesso al database. Non si suppone di salvare se stesso o essere in grado di caricare più istanze di altri episodi. Lo stesso vale per il catalogo, non dovrebbe essere in grado di recuperare il suo ultimo episodio stesso. Un catalogo è un modello, ha un titolo e altre cose.

Dividere le responsabilità

Ottenere materiale da e salvare cose in un DataBase non è una responsabilità dei modelli. Quindi qualcun altro deve fare il lavoro. Un buon inizio potrebbe essere quello di creare un CatalogRepository che potrebbe sembrare così:

CatalogRepository
{
    /**
     * @param int $id
     * @return Catalog
     */
    public function getCatalogById($id)
    {
        //Do a query, populate a new Catalog and return it. 
        //The constructor of Catalog should not be the one quering! 
        //It should receive data, nothing more
    }

    /**
     * @param Catalog $Catalog
     */    
    public function saveCatalog(Catalog $Catalog)
    {
        //stuff....
    }

    /**
     * @param string $name
     * @return Catalog[]
     */    
    public function searchCatalogsByName($name)
    {
        //do a full text search or something?
    }
}

L'episodio avrebbe qualcosa sulla stessa linea in cui potresti ottenere tutti gli episodi per un catalogo specifico ma anche i cinque episodi più popolari:

class EpisodeRepository
{
    /**
     * @param Catalog $Catalog
     * @return Episode[]
     */
    public function getEpisodesByCatalog(Catalog $Catalog)
    {

    }

    /**
     * @param int $amount
     * @return Episode[]
     */
    public function getMostPopularEpisodes($amount)
    {

    }
}

Ci sono alcune linee guida veramente buone per scrivere un buon codice orientato agli oggetti, dai un'occhiata a SOLID per esempio

    
risposta data 21.02.2013 - 11:53
fonte
2

Is this right, or have I made an absolute hash of what OOP is for?

Non è giusto, ma anche non completamente sbagliato.

Il punto principale di OOP è che le classi non sono solo raccolte di metodi, ma contengono anche i dati su cui operano questi metodi - non chiameresti editEpisode($episodeID) , ma $episode->edit() . Questo ha due vantaggi:

  • Minor passaggio di dati, che porta a meno firme di funzioni disordinate e meno potenziale di errori.
  • Rendendo privati i dati (campi), è possibile controllarne l'accesso e consentire solo le operazioni su di esso che hanno senso.

Per un esempio utile del mondo reale, guarda mysqli e confronta il suo procedimento e il suo API OOP. Per quanto riguarda la procedura, è necessario passare un collegamento, un'istruzione o un handle di risultati a quasi tutti i metodi, mentre l'API OOP non ha bisogno di questo perché si chiamano i metodi su un oggetto. Inoltre, i nomi dei metodi OOP non hanno bisogno del prefisso mysqli.

Non è una grande differenza, ma porta ancora a un codice migliore, e ovviamente è solo l'inizio.

    
risposta data 21.02.2013 - 00:25
fonte

Leggi altre domande sui tag