Come implementare il pattern di repository per un'app che cambierà il suo database da sql a nosql in un paio d'anni?

2

Ho letto molto sull'implementazione del repository. Sono confuso su quale modo implementarlo per un progetto, sono sicuro che cambierebbe i suoi metodi del livello dati a causa della migrazione dei db da MS Sql Server a NoSQL tra un paio d'anni.

Imp # 1

  • Implementa il livello di ripetizione come livello completamente separato. Questo avrà la sua interfaccia e i metodi di conversione qui. Questo livello di ripetizione ha a dipendenza da DAL e a sua volta BLL avrà una dipendenza da questo strato

Imp # 2

  • Implementa il repository non come un livello separato ma con le sue interfacce in Business Logic Layer e i metodi in DAL.

Mi sto appoggiando più verso l'imp # 1 perché sembra più pulito. Tuttavia alcune spiegazioni di esperti che ho letto usano imp # 2. Penso che ci debba essere una ragione chiara per usare l'una sull'altra in base alla situazione. Preferirei che il passaggio a un altro database fosse il più indolore possibile.

    
posta Emma 30.01.2015 - 10:58
fonte

3 risposte

1

Il motivo principale per cui avresti le interfacce per i tuoi repository nel tuo BLL è di evitare di avere riferimenti rigidi al DAL separato ma invece di cambiare il riferimento DAL al BLL stabile.

Per poter sostituire le implementazioni senza modificare la BLL stabile

Su Internet questo potrebbe non essere il motivo principale in generale, ma questo sarebbe un motivo convincente per preferire l'opzione 2 nella tua situazione.

Supponiamo che tu stia utilizzando un contenitore DI (iniezione di dipendenza). Se si configura questo utilizzando un file di configurazione, ad esempio, si dirà al contenitore che è possibile trovare le implementazioni per le interfacce del repository nel BLL nel progetto DAL.Sql. Una volta che si passa a una soluzione NoSQL, si crea il progetto DAL.NoSQL, lo si distribuisce e si modifica la configurazione del contenitore DI per risolvere le implementazioni del repository dal nuovo progetto. Il tuo nuovo DAL dipende dalla BLL stabile che non ha bisogno di cambiare.

Tuttavia, se si utilizza l'opzione 1, potrebbe non essere possibile scambiare a caldo il progetto DAL. Ad esempio, se si utilizza .NET, è possibile che si verifichino problemi in cui il progetto BLL dipende da una determinata versione della dll DAL e non sarà possibile sostituire il DAL senza modificare anche il BLL.

Poiché l'interfaccia del repository fa parte della BLL

Un repository è semplicemente un gateway che definisce in che modo la tua applicazione recupererà i dati. In questo senso è tanto una parte della logica di business quanto i tuoi oggetti di dominio. Le implementazioni concrete possono cambiare, ma le interfacce stesse fanno parte della tua logica aziendale.

Perché isola BLL

Avere le interfacce e le implementazioni nel DAL significa portare tutto il DAL nella BLL. Non c'è nulla che impedisca agli sviluppatori di utilizzare oggetti dal progetto DAL in modi che non dovrebbero essere utilizzati. Avere il DAL dipende dal BLL significa che il BLL può contenere solo le interfacce di cui ha bisogno.

Per evitare un progetto separato con gli oggetti dominio

I tuoi DAL e BLL dipendono entrambi dagli oggetti del tuo dominio. Se il BLL ha una classe che utilizza un repository e un oggetto dominio, non è possibile inserire le interfacce del repository nel DAL in quanto crea un riferimento circolare (BLL richiede l'interfaccia per il repository in DAL, DAL richiede oggetti dominio in BLL). Quindi dovresti dividere il BLL e gli oggetti del dominio in due progetti in modo che il tuo BLL possa fare riferimento al dominio e il DAL e il DAL possono anche fare riferimento al dominio.

    
risposta data 30.01.2015 - 12:06
fonte
2

Se si passa all'opzione 1, è possibile modificare la quantità minima di cose quando si passa da un database a un altro, quindi la modifica dovrebbe avere il minimo impatto sull'applicazione in quanto solo i file relativi al database dovranno essere modificati .

Il livello aziendale e qualsiasi altro livello che non ha a che fare con il database non dovrebbe interessare, né conoscere i dettagli di implementazione. Quindi, quando parli di ... e a sua volta BLL avrà una dipendenza da questo livello presumo che tu avresti una serie di interfacce, come IUserRepository o qualcosa del genere che definire metodi come GetUserByName(string name) , ecc.

I layer sopra il repository consumeranno quindi queste interfacce per soddisfare le loro esigenze di dati, questo consentirebbe al livello aziendale di sapere ciò che fornisce il layer del repository, ma non includerà dettagli di implementazione. Pertanto, quando apporti la modifica, per quanto riguarda il livello aziendale, nulla viene modificato (assumendo che non si apportino modifiche alla funzionalità fornita dal livello del repository).

    
risposta data 30.01.2015 - 11:13
fonte
1

@ La risposta di JDT è corretta. Imp # 2 è l'opzione migliore. Il principio di inversione di dipendenza (DIP) come descritto da Robert C. Martin richiede implicitamente che se si dispone di due moduli A e B e un'interfaccia IB implementata da B e immessa in A la definizione di IB dovrebbe essere nel contesto di A .

In realtà è la seconda clausola del DIP che richiede questo:

Abstractions should not depend on details. Details should depend on abstractions.

Nel caso di BLL e DAL il BLL è il modulo di alto livello e il DAL è il modulo di basso livello. Se l'astrazione (le interfacce per i repository, ad es.) Sarebbero definite all'interno del DAL, allora l'astrazione (le interfacce) dipenderebbe dai dettagli (l'implementazione). Se i dettagli cambiano (ad es. Quando si passa all'implementazione del NoSQL DB) anche l'astrazione / le interfacce cambieranno e anche il modulo di alto livello (BLL) dovrà essere modificato. E questo non è desiderato. Quindi chiaramente la risposta alla tua domanda è l'opzione n. 2.

Guardando brevemente per alcune fonti a supporto di questo ho trovato questo su Wikipedia sul DIP :

The interfaces defining the behavior/services required by the high-level component are owned by, and exist within the high-level component's library. The implementation of the high-level component's interface by the low level component requires that the low-level component package depend upon the high-level component for compilation, thus inverting the conventional dependency relationship.

    
risposta data 30.01.2015 - 21:08
fonte