L'implementazione di Spring Data Repository viola il principio dell'accoppiamento lento?

3

Così, al momento mi trovo a costruire la mia struttura di c#/.net (web) (o cartella / progetto / pacchetto -...) spesso come questa, ripensandoci in un "modo un po 'cipolla-architettonico":

myApp
    - API
        - Controllers for HTTP, REST etc., may even be a whole gui, though ...
    - Domain.Model
        - "Business Logic" for the actual application, being most 
           of the time a (micro)service...
        - Interfaces for Repositories, Thirdparty(see below)...
    - Infrastructure
        - ThirdParty
            - Call to other Services,
        - Persistence
            - Implementations for Repositories
        - Adapters
            - Adapt some Class to a DTO for my domain 
    - Config
        - global configurations...
    - Tests
        - empty... just kidding.

In realtà, mi piace molto avere questa separazione, dandomi una buona panoramica su:

  • ciò che è realmente "di valore" al momento (all'interno di Domain.Model)
  • che cosa è solo "presentazione dei dati" (API)
  • che cosa sono "Le dipendenze circostanti che possono cambiare" (Infrastruttura)

Quindi, inizierò un nuovo lavoro tra qualche settimana, tornando al mondo java e faremo un uso massiccio di spring (boot / cloud) per creare una nuova applicazione. Per questo motivo, penso a utilizzare l'ORM hibernate standard del settore, ma inoltre ho trovato molto utile avere un OR-Mapper leggero come JDBI. E in realtà leggo molto sul fatto che Hibernate è lento su larga scala e conosco lo stesso comportamento quando si tratta di entità Framework.

Ora cerco gli esempi di avvio di Spring e ricordo che non è necessario utilizzare un'implementazione di un repository per utilizzare effettivamente il repository utilizzando Spring Data.

Una tipica implementazione di Spring Repository potrebbe essere simile a questa:

Public interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
  ...
}

Quindi, mi sto chiedendo dove mettere questa interfaccia ora? A prima vista, lo inserisco nel mio pacchetto Domain.Model come Interfaccia Repository. Ma non molla "in background" crea un'implementazione effettiva all'interno (!) Del mio dominio.model, quindi, accoppiandolo così con una tecnologia di persistenza, un OR-Mapper e così via?

In .NET, in realtà creo semplicemente un semplice I [Class] Repository all'interno del mio dominio e aggiungo l'effettiva implementazione nella mia Infrastruttura, come Entity Framework o Dapper. Questo mi consente di cambiare facilmente OR-Mapper, anche l'intero DBMS. Quindi, farlo in primavera comporterebbe la creazione di una tonnellata di codice boilerplate per le operazioni CRUD, perché non posso usare l'interfaccia CrudRepository o ho sbagliato qui?

Quindi, sarebbe meglio semplicemente creare un "semplice" repository all'interno del mio dominio.model? Ma non sarebbe solo l'inizio per la tonnellata di boilerplatecode che in realtà voglio evitare?

Forse non dovrei "lavorare contro il framework" qui, perché, in ultima analisi, dovrei farlo anche per ogni altro Call per le spring components, quando voglio essere al 100% con conseguente astrazione del mio dominio dalla tecnologia attuale ..?

Sono un po 'perso qui, in questo momento mi sembra davvero un nodo in testa. Forse mi manca anche qualcosa di ovvio.

Spero che tu possa darmi dei consigli chiarendo come funziona l'implementazione del repository Spring e perché è giusto averlo all'interno di Domain.Model, o mostrarmi il mio malinteso strutturale mentre mi dà consigli su una struttura migliore per i miei progetti.

Grazie in anticipo!

    
posta Dominik 15.04.2017 - 18:42
fonte

1 risposta

0

tl; dr

Does the Spring Data Repository implementation violate the principle of loose coupling?

No. Poiché non esiste un accoppiamento con la sola definizione di un'interfaccia.

Versione lunga

I) In base al layout del tuo progetto e alle tue intenzioni in tal senso, stai vincolando per separare le preoccupazioni (cercando di separare i livelli approssimativamente con API , Domain / Model e Infrastructure come lo chiami). Inoltre ci sono test e configurazione.

La architettura a tre livelli si separa tra presentation tier , middle tier e data tier . Hai due livelli distinti, vale a dire responsabile della presentazione e della persistenza e "le cose nel mezzo".

Quindi da un punto di vista architettonico, la dichiarazione dell'interfaccia appartiene alla "fascia bassa" del livello intermedio mentre comunica con il livello dati:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

da Modelli di architettura aziendale

o potresti metterlo nella "fascia alta" del livello dati come in questo Immagine . Ad ogni modo è distict dagli oggetti del dominio.

Un primo passo per migliorare il tuo design sarebbe quello di inserire le definizioni dell'interfaccia dal tuo Domain -Folder in Infrastructure - Folder

II) Se dai un'occhiata a Spring Data funziona , per attivare la magia devi dichiarare @EnableJpaRepositories("com.acme.repositories") .

This allows me to very easily switch OR-Mappers, even the whole DBMS.

Puoi farlo con Spring come con Entity quadro.

then, thus coupling it to a persistence technology, an OR-Mapper, and so on?

No. Basta coniare il contenitore per scegliere una "implementazione"; ma questo non è accoppiamento. Sei libero di fornirti il tuo.

    
risposta data 16.04.2017 - 07:10
fonte