2012-02-21 13 views
6

Ho bisogno di capire una best practice per l'utilizzo efficiente dei modelli in Zend Framework.Come ottimizzare i modelli in Zend Framework?

Attualmente, ho classi che estendono Zend_Db_Table_Abstract che gestiscono le mie query sulla rispettiva tabella di ogni classe.

Quando ho bisogno di accedere a dire 5 di quelle tabelle da un controller, mi trovo a creare 5 nuove istanze di ogni specifico oggetto Zend_Db_Table. Questo è davvero inefficace.

Ho pensato di implementare un modello di fabbrica per creare nuove istanze (o fornire una copia statica esistente) ma non sono sicuro. È questo il modo migliore per farlo?

Qual è il modo corretto di gestire i modelli garantendo velocità senza consumare risorse eccessive? Il carico pigro dovrebbe entrare in gioco qui?

[EDIT] Per fare un esempio, ho una classe che uso per gestire ottenere informazioni su una località da una query di ricerca prima e bisogno di questi oggetti al fine di analizzare la query:

// Initialize database object 
$this->dbLocations = new Model_Locations; 
$this->dbStates = new Model_States; 
$this->dbZipcodes = new Model_Zipcodes; 
$this->dbLookup = new Model_Lookup; 

In un'altra classe, potrei aver bisogno di accedere nuovamente a quei modelli, quindi ripeto il codice precedente. Reinizializzare in modo sostanziale gli oggetti che potrebbe essere statico/singleton.

+1

La tua domanda è abbastanza salata, puoi mostrare un esempio di codice in cui crei istanze di 5 classi di tabelle e descrivi ciò che ti serve. – markus

+0

Capisco le tue preoccupazioni ma non le seguo davvero. Direi che creare più istanze di una classe e soprattutto una classe astratta è una cosa certa in OOP. Interrogare questo modello di tabella è un po 'come mettere in discussione l'OOP o l'ereditarietà del tutto per me. –

+0

A livello di base, l'utilizzo in questo metodo è accettabile. Ho un "gestore" personalizzato, per mancanza di una parola migliore ", che accetta un oggetto query, analizza le proprietà al suo interno e lo passa a un gestore di posizione che ottiene tutti i dati sulla posizione per quella query, quindi lo passa a un Gestore di dati di marea e gestore di dati meteorologici.In molte fasi di questo, ho bisogno di accedere a varie tabelle e finire per iniziare questi oggetti molto da varie classi.Vedi questo per maggiori informazioni: http://stackoverflow.com/questions/9116838/data-encapsulation-and-data-flow-in-php –

risposta

3

tendo a lavorare al DBTable come fai tu.L'ho trovato efficace quando ho bisogno di interrogare più tabelle in una singola azione per creare un altro livello di modello sopra dbTable. Simile a un livello di servizio o dominio. In questo modo devo solo chiamare un singolo modello, ma ho ancora la funzionalità di cui ho bisogno.

Ecco un semplice esempio che possono eventualmente interagire con 5 classi DBTable e molto probabilmente un paio di classi Row così:

<?php 

class Application_Model_TrackInfo 
{ 


    protected $_track; 
    protected $_bidLocation; 
    protected $_weekend; 
    protected $_shift; 
    protected $_station; 

    public function __construct() { 
     //assign DbTable models to properties for convience 
     $this->_track = new Application_Model_DbTable_Track(); 

    } 

    /** 
    * 
    * @param type $trackId 
    * @return type object 
    */ 
    public function getByTrackId($trackId) { 

     $trackData = $this->_track->fetchRow($trackId); 
     //getAllInfo() Application_Model_Row_TRack 
     $result = $trackData->getAllInfo(); 
     //returns std object reflecting data from 3 DbTable classes 
     return $result; 
    } 

    /** 
    *Get Station from trackid through bidlocationid 
    * 
    * @param type $trackId 
    * @return type object 
    */ 
    public function getStation($trackId){ 

     $data = $this->_track->fetchRow($trackId); 
     //This a Application_Model_Row_Track method 
     $result= $data->getStationFromBidLocation(); 

     return $result; 
    } 

} 

Spero che questo aiuta.

[EDIT] Da quando ho scritto questa risposta ho imparato i benefici di modelli di dominio e Mappers dati. Wow che differenza nella mia app. Non una bacchetta magica, ma un enorme miglioramento.
Grazie alla
Alejandro Gervasio sopra a PHPMaster.com
Rob Allen al Akrabat.com
e
Pádraic Brady a Surviving The Deepend

per tutto il loro aiuto nella comprensione di questo modello.

+0

Ogni volta che si utilizza la classe Application_Model_TrackInfo, fa quello con cui ho un problema. Crea oggetti dbTable che possono o non possono essere usati, quindi vengono eliminati e il tuo prossimo utilizzo crea nuovamente tutto da capo.Queste connessioni dbTable dovrebbero essere generate in un paradigma di fabbrica o sono più istanze concorrenti un overhead accettabile da gestire? –

+0

@cillosis Sembra che tu stia meglio guardando le strategie di memorizzazione nella cache in modo da ridurre al minimo le query Db. Potrebbe essere appropriata anche una soluzione ORM (con una certa persistenza dei dati). – RockyFord

1

Sembra che tu sia in una situazione in cui richiedi un'efficiente gestione dei dati con funzionalità che l'attuale framework Zend non ha. Zend non ha un motore integrato per lavorare con database di qualsiasi tipo, ha semplicemente classi wrapper che ti aiutano a scrivere le tue domande.

Quello che ti serve è un modello relazionale oggetto (ORM) che è un must in un framework professionale. A quanto ho capito, ORM è un framework di per sé, ha schemi e modi fortemente definiti di "fare cose", supporta il caricamento pigro (ne prende il massimo) e ottimizza le query al meglio. Quando si utilizza ORM non si scrive nemmeno SQL, ma è necessario modificare la propria interpretazione della memorizzazione dei dati, è necessario dimenticare le tabelle e concentrarsi sugli oggetti. Ad esempio, in Doctrine ogni tipo (tabella) viene specificato da una classe e ogni record (riga) come istanza di classe in cui è possibile accedere a metodi e proprietà differenti. Supporta gli ascoltatori di eventi e le rellazioni a cascata pazzesche.

Non è più necessario estrarre le righe dalle tabelle correlate quando si eliminano i record (è automatico), non è più necessario scrivere script complessi e caotici per garantire la sincronizzazione del file system, è possibile eseguire la migrazione a quasi tutti i motori di database in qualsiasi momento (mysql , postgresql, simplesql ..) e altro ..

Ho usato Doctrine 2 in combinazione con Symfony 2 framework e devo dire che non tornerò su Zend per niente. Sì, è complesso e pesante, ma davvero la soluzione definitiva. Quando arrivi a un momento in cui devi gestire centinaia di tabelle con milioni di record totali, allora vedrai la differenza.

Quindi, la sommatoria finale: ORM è quello che ti serve, ci sono molte soluzioni, ne conosco due veramente buoni: Doctrine 1 o 2 e Propel.

PS: ORM è una parte indipendente del sistema, in modo che non si ha realmente bisogno di utilizzare un quadro specifico, Zend può essere configurato per lavorare con Dottrina meravigliosamente :)

+4

Zend_Db È di per sé un'implementazione del pattern ORM. La tua risposta non affronta il vero problema dell'OP, ma gli dice di cambiare lo strumento in base al tuo punto di vista personale. Il tuo primo paragrafo è completamente sbagliato, il che suggerisce che stai parlando di abo cose che in realtà non conosci. – markus

+0

Sì, e il tuo affronta il problema completamente. –

+0

Non ne ho scritto nessuno, perché per il momento non ci sono abbastanza informazioni nella domanda per scrivere una risposta. – markus