Per un repository SQL concreto, dovrei incapsulare la logica SQL all'interno o all'esterno dei metodi del repository?

3

Se dispongo di un repository concreto basato su SQL di accesso ai dati, dovrei passare in SQL ai metodi del repository o incapsularli all'interno dei metodi. Sento che se li passo, allora sono coupling my repository with SQL data access , quindi mi sto appoggiando a mettere SQL in the methods ? Ecco le mie due opzioni:

public GetPeople(string sql)
{
   //Query people with passed in sql
}

public GetPeople()
{
  //Query people with sql logic here, possibly conditional logic
}
    
posta xaisoft 23.03.2015 - 03:11
fonte

2 risposte

3

Passare SQL nel repository non è sicuramente un buon modo per fare le cose. Viola il principio di responsabilità singola perché il client utilizza il repository e gli dice anche come lavorare invece di usare il repository e il repository sapendo come funzionare da solo.

    
risposta data 23.03.2015 - 03:19
fonte
2

Come sempre, è utile pensare ai pro e ai contro di ciascun approccio:

Passaggio Pro in SQL

  • È flessibile. Se disponi di molte query diverse che sono difficili da parametrizzare, non ti ritroverai con un sacco di metodi o dovrai progettare intorno ad esso.

Anti passing in SQL

  • In genere è una cattiva idea presentare un'interfaccia più grande del necessario. L'interfaccia potrebbe non sembrare più grande - è ancora un metodo - ma promette enorme di "Datemi praticamente QUALSIASI domanda e la eseguirò per voi". Questo può essere molto problematico, ad esempio, nel test, perché ora invece di testare una classe che afferma di poter rispondere a una domanda specifica, devi testare una classe che afferma di poter rispondere a qualsiasi domanda. La stessa difficoltà si pone se si sta prendendo in giro il repository anziché testarlo.

  • Si finisce senza alcuna separazione delle preoccupazioni. I timori SQL saranno spruzzati attraverso il tuo codice base; indipendentemente da quale sia la responsabilità di una classe, implicherà anche implicitamente l'esatta implementazione e struttura della persistenza. Sarà molto più difficile scrivere codice non conforme o codice conforme alla singola responsabilità.

  • Per i dati che possono essere solo uno di un piccolo numero fisso di valori, di solito è consigliabile utilizzare un enum . Questo è essenzialmente dovuto al fatto che il compilatore non può eseguire il peer all'interno delle stringhe, non è in grado di riconoscere gli errori di battitura, l'IDE non può fornire intellisense in base ai valori di stringa e così via. Vuoi essere strongmente digitato piuttosto che " digitato in modo stringato ".

    Quindi, se ciò è importante per i dati semplici, pensa quanto sia più importante per code . L'ultima cosa che vuoi è avere un comportamento dentro le stringhe, con errori di battitura che causano errori di runtime, test di unità completamente impossibili, nessuna intelligenza, nessun passaggio con un debugger, nessuna delle cose belle che riceviamo scrivendo codice come codice piuttosto che come valori stringa.

    Ovviamente avrete bisogno che il vostro SQL sia da qualche parte, ma come parte di un metodo di repository è isolato da qualche parte che l'intero metodo può essere testato come un'unità sensibile. E al di fuori dei tuoi repository, le query che desideri eseguire saranno rappresentate come metodi richiamati su objects , anziché come valori all'interno di stringhe .

Come puoi vedere, questa lista è un po 'unilaterale. Il tipo di "flessibilità" che ottieni è davvero il peggiore, analogo all'aggiunta di params object[] extra a tutti i metodi nel caso in cui ne avessi bisogno in futuro. Anche se non ci fosse una così grossa collezione di svantaggi, sarebbe comunque una YAGNI violazione. Quindi raccomando vivamente di non passare in SQL, certamente non come punto di partenza per il repository.

Se lo fai, ad un certo punto nel futuro, ti trovi nella situazione abbastanza insolita in cui devi fare molte, molte domande diverse, e le differenze tra loro sono qualcosa di difficile da parametrizzare semplicemente, ci sono probabilmente ancora migliori modi per affrontare questo che passare in SQL. Ad esempio, è possibile creare classi che possono essere utilizzate per creare query mediante l'utilizzo di metodi, che espongono quindi l'SQL finale come proprietà. Ma sicuramente questo scenario non vale la pena di pianificare prematuramente.

    
risposta data 23.03.2015 - 13:56
fonte

Leggi altre domande sui tag