Esiste un modo migliore per caricare gli oggetti?

2

Ho sempre mantenuto il codice per caricare un oggetto all'interno dell'oggetto stesso. In questo modo, indipendentemente dal metodo che sta creando l'oggetto, ha sempre accesso al metodo per caricare l'oggetto. Tuttavia questo significa che se sto caricando un sacco di oggetti devo creare una copia vuota di un oggetto per recuperare una matrice di oggetti, e non sembra essere il modo più logico di caricare una matrice di oggetti. Prendi questo codice come esempio, una pagina sta caricando un sacco di prodotti.

class Product() {

    // product variables...

    public function LoadProducts($dbConn, $where) {
        $products = array();
        $query = "SELECT * FROM products $where";
        $results = $dbConn->query($query);
        while($row = $results->fetch_assoc()) {
            $products[$row['pId']] = new Product();
            $products[$row['pId']]->StoreVars($row);
        }
        return $products;
    }

    public function StoreVars($row) {
        foreach($row as $key => $val) {
            $this->$key = $val;
        }
    }

}


class Page() {

    // page variables...

    public function DrawPage($dbConn) {
        $product = new Product();
        $where = "Some where clause";
        $products = $product->LoadProducts($dbConn, $where);
        // Do something with products to output HTML to the page...
    }

}

La maggior parte dei miei oggetti come product seguono un modello simile. Questa è una buona pratica? C'è un modo diverso / standard per farlo? Sto facendo questo correttamente? Mi sembra un po 'inutile chiamare un'istanza vuota di prodotto per caricare tutti i prodotti, ma non so dove altro mettere quella funzione, quindi non devo avere molte copie della stessa query.

    
posta Styphon 11.07.2014 - 16:46
fonte

3 risposte

5

Potresti considerare di rendere LoadProducts () un metodo statico, in modo da non dover creare un'istanza di un oggetto vuoto per caricare un elenco di prodotti:

class Product {
   public static function LoadProducts(...)
   {
   }
}

e quindi è solo

$products = Product::LoadProducts( ...)
    
risposta data 11.07.2014 - 18:02
fonte
2

Un oggetto che si carica da solo non è possibile.

Si può dire che la Classe di un oggetto è responsabile di caricare le sue istanze. Ma poi si assegna la responsabilità "caricando" alla responsabilità "modello per oggetti" all'oggetto di classe in modo da violare SRP (principio di responsabilità singola). Inoltre finirai con metodi statici che hanno almeno qualche effetto sulla testabilità.

Per seguire il percorso di SRP, la responsabilità ricade in una classe di oggetti completamente diversa che soddisfa alcuni altri requisiti molto importanti.

  1. Chi sa meglio caricare un oggetto?
  2. Chi sa meglio aggiornare un oggetto in modo valido?
  3. Chi è il migliore per eliminare un oggetto?

La risposta a tutte e tre le domande è: Colui che ha creato l'oggetto.

Come puoi riconoscere: le operazioni menzionate sono le operazioni CRUD. Quindi, per scopi di simmetria, tutte le operazioni CRUD esistenziali per un oggetto devono essere legate a un oggetto responsabile.

Finalmente finirai con Repository o Tao .

Ma attenzione: i repository e DAO sono astratti solo dal tipo di accesso a un datalayer e non sono responsabili della coerenza. La coerenza deve essere gestita nel livello aziendale (Business-Objects, Domain-Objects).

    
risposta data 29.07.2017 - 12:39
fonte
0

Utilizzare un metodo statico come suggerito da GrandmasterB è sicuramente un passo nella giusta direzione, ma penso che non dovresti avere codice per il caricamento in questa classe. Dovresti provare a seguire il Principio di Responsabilità Unica e rendere le tue lezioni più mirate, indipendenti e modulari possibili, in modo da non vincolarle a una determinata implementazione per caricarle. Disaccoppiare le classi dal loro contesto le rende più robuste, più flessibili e più facili da testare.

    
risposta data 11.07.2014 - 20:56
fonte

Leggi altre domande sui tag