Livello di servizio dell'applicazione che chiama le funzioni del database. Cattiva architettura?


11

Scenario:

  • Stack: Java, Spring, Hibernate.
  • Modello: applicazione client-server.
  • Modello: Model-View-Controller (MVC).

Le classi del livello di servizio hanno tre comportamenti:

  1. Alcuni servizi hanno la regola aziendale all'interno dei metodi e delegano la persistenza all'applicazione. Piace:

    EntityManager.save (entità);

  2. Alcuni servizi chiamano semplicemente una funzione di database (passando parametri) Come:

    CallableStatement cls = con.prepareCall ("{call databaseFunction (args)}");

  3. Alcuni servizi hanno metodi con entrambi i comportamenti.

Le mie domande:

  1. C'è qualche problema ad avere i servizi dell'applicazione che chiamano direttamente le funzioni del database? Non è considerata una cattiva pratica? Quale sarebbe un modello di architettura applicabile a un progetto come questo?
  2. C'è qualche problema ad avere il mix di comportamenti nello stesso servizio? Come transazioni e coerenza?
  3. In caso di manutenzione, questo incapsulamento rende oscuro allo sviluppatore che dovrebbe anche modificare le funzioni nel database? Come evitarlo?
  4. Questo scenario si verifica in altre applicazioni in tutto il mondo o è stato solo un errore architettonico?

Questa domanda è simile ma non esattamente la stessa .. softwareengineering.stackexchange.com/questions/180012/…
Jon Raynor,

Risposte:


7

C'è qualche problema ad avere i servizi dell'applicazione che chiamano direttamente le funzioni del database? Non è considerata una cattiva pratica?

Penso che ci sia. Stai mettendo una conoscenza degli interni del database al servizio dell'applicazione. La modifica del database in qualsiasi modo (modifica del motore di archiviazione o persino la ridenominazione di un campo o la creazione di un indice) potrebbe richiedere la modifica del servizio dell'applicazione e ciò viola la SRP .

Quale sarebbe un modello di architettura applicabile a un progetto come questo?

Vedi il commento qui sotto.

C'è qualche problema ad avere il mix di comportamenti nello stesso servizio? Come transazioni e coerenza?

Non credo ci sia un problema tecnico, ma ce n'è uno logico. Basta mescolare due approcci nell'applicazione rendendolo vago, meno strutturato, difficile da adattare ai cambiamenti. Vedi anche i commenti sopra sulla violazione di SRP.

In caso di manutenzione, questo incapsulamento rende oscuro allo sviluppatore che dovrebbe anche modificare le funzioni nel database?

Certo che lo fa.

Come evitarlo?

Posiziona metodi e funzioni, che funzionano direttamente con il database in un livello separato di astrazione (che si tratti di un livello DAO o di un modello di repository semplice, dipende dalla complessità dell'applicazione)

Questo scenario si verifica in altre applicazioni in tutto il mondo o è stato solo un errore architettonico?

Penso che nel nostro mondo tutto accada;)


Se capisco correttamente, potrebbe esserci un problema tecnico in quanto se si verificano aggiornamenti in funzioni / stored procedure e anche tramite un ORM, gli stati di una determinata transazione sono molto difficili da ragionare. Mentre l'applicazione potrebbe funzionare nel suo stato attuale, una piccola modifica potrebbe precipitare in alcuni problemi davvero grandi. La mia esperienza con Hibernate è che se non gli permetti di gestire l'intero set di tabelle con cui funziona, avrai molti fastidiosi problemi.
JimmyJames,

risposta simpatica e concisa. SRP è stata la prima cosa che mi è venuta in mente quando ho guardato il codice per la prima volta. Alcuni colleghi affermano che il metodo non viola SRP a causa del fatto che chiama solo la funzione di database. Ma alcune di queste funzioni selezionano, inseriscono e aggiornano. Quindi viola o meno SRP? (forse questa è un'altra domanda da discutere separatamente?)
linuxunil,

1
+1 per quella linea penso che nel nostro mondo tutto accada;)
linuxunil

@linuxunil SRP dovrebbe essere rispettato a tutti i livelli di architettura. Nel mio caso intendevo SRP a livello di servizio, non a livello di metodo. @ JimmyJames Yep. La maggior parte degli ORM non funziona bene con le stored procedure. Ma a volte sono necessari processi memorizzati.
Vladislav Rastrusny l'

3

Secondo quello che hai detto c'è un livello di servizio, quindi il modello architettonico che sembra adatto è l'architettura a strati. Ulteriore riferimento

Sì, di solito è una cattiva pratica effettuare chiamate dirette al database oltre a un livello di accesso ai dati, in questo modo il livello aziendale accede solo a un'astrazione del database.

Per quanto riguarda i comportamenti di mixaggio, l'uso di alcuni pattern di design come pattern DAO o Repository potrebbe aiutare a delegare tali responsabilità migliorando così quel codice.

Alcuni dei vantaggi dell'utilizzo di un modello di progettazione e di un ORM sono la leggibilità del codice, l'incapsulamento delle responsabilità, quindi se l'accesso al database cambia il livello aziendale non dovrebbe cambiare molto.


Non sono sicuro del perché sia ​​stato votato in negativo. Questa risposta raccomanda di separare il codice che affronta problematiche diverse . Sembra un preside della programmazione qui ... non sono sicuro di cosa sia ... Amico. Se solo potessi pensare al nome. +1 BTW
Greg Burghardt,

Non è uno dei principi solidi?
J. Pichardo,

3
No. La "S" in SOLID rappresenta l' S ingle Responsabilità Principal (SRP). Ma la separazione delle preoccupazioni, che stai raccomandando, è un motivo valido per separare la logica di servizio dalla logica di accesso ai dati. L'altra risposta di Vladislav menziona il Responsabile unico responsabile. Francamente, The SRP e Separation of Concerns vanno bene insieme, come vino e formaggio.
Greg Burghardt,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.