Dal punto di vista di OOP, tenendo conto delle prestazioni - una connessione di database dovrebbe essere un campo statico, un campo istanza o una variabile locale?

3

Quando i metodi usano una connessione al database, la connessione deve essere un campo statico, un campo istanza o una variabile locale?

Ecco i miei dubbi. Ho scelto i dithering corretti e che sono privi di fondamento. Ho cercato di dare delle fonti alle mie supposizioni, ma la maggior parte di esse deriva da cose che ho letto qua e là, e probabilmente non ho capito bene:

static campi:

Pros:

Cons:

  • This is practically creating a global variable*, which is considered bad in OOP.
    *Perhaps you could refer to the connection as global constant which is not concidered bad programming?
  • Sometimes fields are referred as states since they describe the state of the class. But logically, the connection do not describe the class, the class's methods just use it.

campi di istanze:

Pros:

  • DRY - You can use the connection from any method in the class.
  • Shorter code (Again, not always good).

Cons:

  • Again, logically, the connection does not describe the object, the object's methods just use it.

variabile locale (metodo):

Pros:

  • Methods open the connection only when they need it*.
    *Although, even using a field, you could use the using statement to close the connection when needed.

Cons:

  • DRY - Very repetitive code.

Quindi, come ho detto, posso vedere i vantaggi e gli svantaggi dei tre approcci. Ma qual è l'approccio più comune e, cosa più importante, l'approccio più accurato dal punto di vista dell'OOP? E quale approccio porta a prestazioni migliori?

Grazie.

    
posta Sipo 15.05.2016 - 08:00
fonte

4 risposte

5

In generale, quando le connessioni database utilizzate sono variabili locali, poiché vengono quasi sempre recuperate da una fabbrica per semplificare l'astrazione dei dettagli di implementazione. Pragmaticamente , quei dettagli contano visto che quasi sempre vuoi mettere in comune le connessioni del tuo database, e la fabbrica gestisce tutto ciò.

La factory a sua volta di solito è una variabile di istanza poiché spesso si desidera la flessibilità di utilizzare istanze diverse laddove necessario.

    
risposta data 15.05.2016 - 14:04
fonte
1

In primo luogo, facciamo una dichiarazione chiara sulle prestazioni: nel 99,99% di tutti i casi reali le prestazioni saranno letteralmente le stesse, quindi - come al solito - le prestazioni non sono un criterio utile per prendere una decisione del genere.

Le domande principali che dovresti porci qui sono:

  • "posso immaginare una situazione in cui ho bisogno di connessioni di database diverse per funzioni diverse nella mia classe" (o anche per la stessa funzione all'interno dello stesso oggetto, quando viene chiamato in un contesto multithreading, ad esempio)?

  • "devo aspettarmi un bisogno di connessioni di database differenti per oggetti diversi", oppure devo supporre che non ci sia sempre un "contesto globale" disponibile dove potrebbe essere disponibile la "connessione globale db" ( per esempio, in una situazione di test)?

  • "Sono sicuro al 100% che tutto il mio programma / libreria si connetterà sempre a un solo database, e non ci sarà mai bisogno di usare una connessione / database diversi allo stesso tempo?"

Se la risposta alla prima domanda è "sì", è chiaro che hai bisogno della connessione come parametro per le tue funzioni. Se la risposta al primo è "no", ma al secondo è "sì", si dovrebbero campi di istanza. E se la risposta alla terza domanda è "sì", puoi utilizzare una "variabile globale" (o un campo statico), probabilmente evitando un codice di tipo standard.

Quindi tutto si riduce a "non esiste l'unica soluzione migliore". Dipende dal tipo di programma che stai scrivendo, è un'applicazione che usa sempre un db o molti, è una libreria che potrebbe potenzialmente utilizzare nuovamente database diversi allo stesso tempo, e così via. Quindi la soluzione "migliore" è quella che soddisfa meglio le tue esigenze.

    
risposta data 19.05.2016 - 13:25
fonte
0

Una classe di configurazione è probabilmente la migliore in quanto sarà DRY e implementerà un'interfaccia (lo mantiene testabile). L'interfaccia deve avere un metodo che accetta stringhe SQL e restituisce un oggetto.

Diverse implementazioni possono essere fatte per ambienti diversi.

    
risposta data 19.05.2016 - 12:59
fonte
0

Risposta breve: dal punto di vista di OOP questo dovrebbe essere un dettaglio di implementazione.

È possibile nascondere questo dettaglio di implementazione se si dispone di un metodo di istanza che viene utilizzato come variabile del metodo locale. In questo modo le tue tre opzioni sono dettagli di implementazione che possono essere facilmente modificati in qualsiasi momento con poche righe di codice:

class MyService {
    protected DBConnection getDBConnection() {
        return new DBConnection(...); // version 3: local variable in method
    }
    protected void closeDBConnection(DBConnection con) {
        con.close(); // version 3: local variable in method
    }

    doSomething() {
        protected DBConnection con = getDBConnection();
        ...
        closeDBConnection(con);     
    }
}

La modifica dei dettagli di implementazione alla versione 1 o 2 richiede solo di modificare getDBConnection () e closeDBConnection () senza influire sui servicemets doSomething1 (), doSomething2 (), ...

la versione statica diventerebbe

class MyService {
    private static DBConnection sConnection = null;
    protected DBConnection getDBConnection() {
        if (sConnection == null) sConnection = new DBConnection(...);
        return sConnection;
    }
    protected void closeDBConnection(DBConnection con) {
        // do nothing
    }
 }

Il modello di progettazione per questo è chiamato "Metodo di fabbrica".

    
risposta data 20.05.2016 - 09:08
fonte

Leggi altre domande sui tag