Ho progettato un livello di accesso al database che ci consente di supportare più database nei nostri programmi. Alla fine, gli utenti dei nostri programmi dovranno essere in grado di scegliere il sistema di database sottostante da una serie di sistemi di database. Alcuni piccoli clienti potrebbero essere felici con MS Access, altri preferiscono MySql, altri DB2. Quei sistemi db sono quelli che voglio prendere di mira per ora.Domanda di progettazione livello database
Dati questi requisiti, ho creato una classe astratta DatabaseConnection. Internamente, utilizzo la classe System.Data.Common.Data.DbConnection, che mi dà già un po 'di flessibilità.
Le cose che richiedono istanze concrete (OleDbCommand anziché DbCommand ad es.) Sono nascoste in metodi astratti come CreateDbCommand(). Sottoclassi (come AccessDbConnection) implementano quelle e forniscono le istanze concrete. Attualmente che porta a questa gerarchia (nomi di classe abbreviati per migliorare la leggibilità):
DatabaseConnection / | \ AccessConn MySqlConn DB2Conn
Tuttavia, ci sono alcune operazioni che sono specifici per il sistema di database sottostante, come ad esempio il recupero di tutti i nomi di tabella. È sbagliato posizionare un metodo astratto GetTableNames() nella classe DatabaseConnection e fare in modo che le sottoclassi lo sovrascrivano.
Ho pensato che forse posso creare un'altra classe base astratta chiamata DatabaseTools, dichiarare quelle operazioni lì e quindi implementarle in sottoclassi che assomigliano alle sottoclassi della classe DatabaseConnection. Il che significa che per un AccessDbConnection, mi piacerebbe anche avere una classe AccessTools etc etc:
DatabaseConnection DatabaseTools / | \ / | \ AccessConn MySqlConn DB2Conn AccessTools MySqlTools DB2Tools
In qualche modo io non sono davvero entusiasta da questa idea.
Quali idee avete per risolvere questo problema di progettazione?
Grazie in anticipo per il vostro tempo e le risposte :)
Acclamazioni
Christian
Quello che si preoccupa per il design? Mi sembra ragionevole (a prima vista). Vorrei includere un modo per garantire che non si possa usare un 'AccessTools' con un' MySQLConn', ma questa è l'unica cosa che riesco a pensare. – ChrisF
Penso che l'approccio al metodo astratto sia corretto. Quale motivo convincente puoi dare per aver violato il rasoio di Occam e il principio KISS e aver creato un secondo set di classi in cui sarebbe bastato? Ho usato la prima architettura che hai descritto in una mezza dozzina di progetti e non ho mai avuto problemi con essa. Non c'è solo un sacco di codice specifico per DB che è richiesto, purché si rispetti lo standard SQL. –
@ChrisF: Quando penso a una classe DatabaseConnection, la penso semplicemente come la connessione stessa, che mi consente di creare, aprire e chiudere la connessione. Interrogare tutti i nomi delle tabelle e altre operazioni specifiche del sistema db devono fare qualcosa con la connessione (dopotutto, operano su di esso), ma ritengo che non debbano essere legati alla connessione troppo stretta. – Christian