È questo cattivo design? Come può essere migliorato?

9

Ho scritto quanto segue qualche tempo fa, ma sono venuto a leggerlo di recente, e ora non penso che sia un buon progetto.

Il design è per un tipo di strato di database modulare che utilizza Entity Framework 4. Esiste un singolo oggetto di database che carica (impercettibilmente) i contesti del framework di entità da librerie esterne in una posizione specificata, e le istanze dei contesti caricati sono memorizzate in un tabella hash contro il loro nome (EG "ContentMgmtContext").

Tutti i contatti con il database in questo sistema sono attraverso stored procedure. Per effettuare una chiamata al database, la firma del metodo di query ha il seguente aspetto:

List<TReturn> Query<TReturn>(string Context, 
                             string Procedure, 
                             TransactionScope Scope, 
                             List<ObjectParameter> QueryParameters)

Questa modularità è qualcosa che mi piace. Tuttavia, questo approccio presenta uno svantaggio significativo: when using the database layer, the code using it has to have a reference to the library in which the context is stored, in order to access the types returned by the stored procedures through Entity Framework. Nel modello, gli oggetti dal livello del database vengono tradotti in nuovi oggetti utilizzati dalla vista e dal controller.

Penso che questo sia un cattivo design, ma come posso migliorarlo? Ho preso in considerazione l'aggiunta di un'interfaccia vuota come IStoredProecedureObject per dare a ogni tipo di dati restituito da una stored procedure un tipo di base comune, tuttavia questo sembra essere sventato da Entity Framework. Ogni volta che il file .edmx viene ricompilato, il codice viene generato di nuovo e tutte le aggiunte rimosse. C'è un modo per fermare questo evento?

Come posso migliorare questo design? Che (altro) ha sbagliato? O sono sulla strada giusta?

    
posta Andy Hunt 28.12.2011 - 02:16
fonte

1 risposta

6

Dichiarazione di non responsabilità: non utilizzo il framework di entità e sono pesantemente sbilanciato contro qualsiasi framework di helper di database.

Sembra che tu abbia creato un wrapper.

Faccio una distinzione tra "wrapper" e "layer". Il livello è qualcosa che potresti compilare alla sua DLL / progetto / Jar / qualunque. Il livello di accesso ai dati. Wrapper è una classe "helper" che usi all'interno di quella DLL. Con lo scopo di semplificare l'interfaccia, o forse eliminare la duplicazione.

Il problema con la semplificazione dell'interfaccia dell'accesso al database è che non è semplice. Si finisce per duplicare l'interfaccia di ADO / JDBC / etc. O costringi le persone a bypassarlo. I wrapper tendono a fare ogni sorta di cose indesiderate. Possono chiudere automaticamente una connessione quando ne hai bisogno, aprire per supportare una transazione. Spesso lasciano erroneamente aperte le connessioni se si hanno a disposizione dati in streaming e si sta utilizzando uno di questi linguaggi di raccolta dati obsoleti. Per dare tutta la potenza della libreria dietro il tuo wrapper sei costretto a duplicarlo.

Le librerie come ADO / JDBC sono già un'interfaccia GRANDE. Sono alcuni dei migliori esempi di OOP fatti bene. Preferirei usarli su un involucro che un wizbang ha tirato fuori dal suo cappello.

La classica interfaccia in stile JDBC / ADO è ben conosciuta e compresa. L'involucro che hai estratto dal tuo cappello non lo è.

Vuoi ridurre "paramters.Add" ridondanti? Guarda nei generici. O semplicemente accettando che provando a ridurre "paramter.Add" in realtà basta semplicemente ".add" su un altro livello di codice.

BTW questa è una grande domanda. Lo avrei votato per 10 volte se potessi.

Modifica: Ovviamente il codice JDBC verrebbe nascosto nel livello di accesso ai dati.

    
risposta data 28.12.2011 - 05:23
fonte

Leggi altre domande sui tag