Quali di questi esempi di OOP dimostrano i concetti OOP appropriati?

4

Sto ancora cercando di avvolgere la mia mente attorno a OOP. Tutti gli esempi seguenti funzionano, naturalmente, ma c'è uno (o forse un altro) che meglio esemplifica i concetti OOP?

/**
 * For the following examples the Image class queries an image
 * and associated info from a database, which is passed on
 * instantiation via dependency injection.
 */

$image = new Image(new Db());

Esempio 1:

if ($image->setImageId($id, $size)) {
    header('content-type: ' . $image->content_type);
    header('content-length: ' . $image->length);
    echo $image->getBytes();
}

Esempio 2:

if ($image_info = $image->getImageInfoByIdAndSize($id, $size)) {
    header('content-type: ' . $image_info->content_type);
    header('content-length: ' . $image_info->length);
    echo $image->getImageBytesByIdAndSize($id, $size);
}

Esempio 3:

$image->setImageIdAndSize($id, $size);

if ($image_info = $image->getImageInfo()) {
    header('content-type: ' . $image_info->content_type);
    header('content-length: ' . $image_info->length);
    echo $image->getImageBytes();
}
    
posta Isius 01.03.2013 - 21:39
fonte

3 risposte

6

La classe Image ha due responsabilità che dovrebbero essere separate:

  • Accesso al database astratto
  • Incapsula le informazioni sull'immagine

Estrai l'accesso al database in un oggetto di accesso ai dati (DAO).

class ImageDao
{
    private $db;

    public function __construct(Db $db) {
        $this->db = $db;
    }

    public function findByIdAndSize($id, $size) {
        return new Image($db->exec(...));
    }
}

Questo libera Image per fare ciò che dovrebbe: memorizzare informazioni su un'immagine e possibilmente fornire metodi per manipolarla.

    
risposta data 02.03.2013 - 22:28
fonte
2

Personalmente preferisco # 1.

# 2 sembra quasi che tu stia cercando di usare un pattern singleton, dove potresti avere dozzine di tali chiamate di fila con ID $ diversi ogni volta sullo stesso oggetto. Se questo è il tuo intento, dovresti probabilmente andare fino in fondo e effettuare chiamate come Image::getImageBytes($id)

# 2 e # 3 sono entrambi strani, perché sembra che tu stia caricando una specie di dati sidecar. Questo andrebbe bene se la composizione dell'oggetto fosse tale che i dati di questa side car potrebbero rappresentare un'altra query al DB (come se ci fosse una tabella nel tuo db chiamata 'ImageComments' e volessi usare $ image- > getImageComments () per restituire una serie di 'ImageComments') OPPURE una risorsa condivisa di cui potrebbero aver bisogno più immagini (come dire una galleria genitore) ma sembra improbabile che un'immagine (specialmente con una dimensione selezionabile) abbia un 'image_info' memorizzato e tanto meno probabilmente lo condividerebbe con altre immagini.

Potrei suggerire di utilizzare metodi pubblici (ad esempio $image->length() ) invece di variabili di istanza pubbliche per migliorarne uno (ma soprattutto il numero 1). Ciò consentirebbe di fare cose semplici come il ritardo che in realtà carica i dati dal DB fino a quando non è effettivamente necessario. E nel caso di qualsiasi dato sidecar come discusso in precedenza, i metodi potrebbero occuparsi di fare tutto il lavoro di background necessario per eseguire l'attività (ad esempio public function getImageComments() { return $this->DB("SELECT * FROM 'ImageComments' WHERE image_id = {$this->_id}"); } )

    
risposta data 02.03.2013 - 06:49
fonte
0

Per qualcosa di simile, in cui i dati sono (probabilmente) immutabili una volta caricati nell'oggetto, dovresti davvero avere una sorta di ImageFactory che incapsula il caricamento delle immagini, in questo modo la classe Image può essere immutabili.

    
risposta data 15.03.2013 - 14:05
fonte

Leggi altre domande sui tag